Re: StackOverflow Exception in JNI
From: Gordon Beaton (not_at_for.email)
Date: 06/10/04
- Next message: Andrew Thompson: "Re: Java API for correcting malformed HTML code"
- Previous message: Andy Fish: "Re: Throw and catch exception in 2 classes"
- In reply to: Bryan Castillo: "StackOverflow Exception in JNI"
- Next in thread: Bryan Castillo: "Re: StackOverflow Exception in JNI"
- Reply: Bryan Castillo: "Re: StackOverflow Exception in JNI"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 10 Jun 2004 09:29:53 +0200
On 9 Jun 2004 20:44:49 -0700, Bryan Castillo wrote:
> I'm getting a StackOverflow exception while using JNI.
>
> I have a loop written in C/JNI which calls back a Java object (which
> conforms to some interface). The loop is creating 2 byte arrays and
> giving them to the object being called back. The arrays are being
> created with the function NewByteArray. For some reason around
> 50,000 items into the iteration, I run into a StackOverflow
> exception. I'm not actually doing anything with the byte arrays once
> passing to the callback. (In the JNI code the byte arrays are not
> returned). Should I be deleting them using DeleteLocalRef? (I'll try
> tomorrow - forgot to bring the code home with me).
Without seeing your code, it's impossible to say what is causing your
exception. Presumably there is a recursive call somewhere.
In most normal situations, you don't need to explicitly free any
objects in your native code, that will be taken care of automatically
when the method returns. The regular reachability rules apply and the
objects become eligible for garbage collection at the end of the
method, while objects returned to java or still referenced by other
live objects will continue to be valid. In other words, you can create
temporary objects in your native method and then return a valid
reference without thinking too much about these issues.
If you create many temporary objects in the native method without an
intervening return, the objects will accumulate and you can cause an
out of memory situation. A typical scenario is a (native) loop where a
handful of objects are created on each pass and only used during that
specific pass of the loop.
To avoid that situation you can call DeleteLocalRef() on each
temporary reference at the end of every pass, or define a local stack
frame for the loop by enclosing the loop body in calls to
PushLocalFrame() and PopLocalFrame(). PopLocalFrame() is essentially
the same as calling DeleteLocalRef() on each reference created within
the frame, except for one that you can tell it to return to the
enclosing frame.
> [side question]
> Is the array returned from NewByteArray a local reference or global?
> I thought it was a local reference. But if that is true should you
> use NewGlobalRef before returning the byte array back to java code?
> Currently, im just returning the jbyteArray and everything seems to
> be working so far.
All references you create are local until you explicitly create a
global reference with NewGlobalRef().
However you only need to use NewGlobalRef() if you want to save a
reference across multiple calls to the native code (there may be other
situations but I can't think of any off hand). If you use
NewGlobalRef() on a return value, that object will not become eligible
for garbage collection until you explicitly free it.
You don't need to create a global reference for values you return back
to Java, or pass to other methods invoked from the native method.
/gordon
-- [ do not email me copies of your followups ] g o r d o n + n e w s @ b a l d e r 1 3 . s e
- Next message: Andrew Thompson: "Re: Java API for correcting malformed HTML code"
- Previous message: Andy Fish: "Re: Throw and catch exception in 2 classes"
- In reply to: Bryan Castillo: "StackOverflow Exception in JNI"
- Next in thread: Bryan Castillo: "Re: StackOverflow Exception in JNI"
- Reply: Bryan Castillo: "Re: StackOverflow Exception in JNI"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|