Android Jni: crash in ref global and local variables

I have jni C ++ code that calls java objects like:

jclass JIOManager = CJavaEnv::getInstance()->env()->FindClass(ioManagerName);

    ..... some code

CJavaEnv::getInstance()->env()->DeleteLocalRef(JIOManager);

      

this works fine when executed on the main thread, but when i try to execute it on another thread it crashes because it says it was created on another thread: O !! but after I read on the google android developer website they say that accessing the Global Ref from any thread is fine, so I changed this code.

jclass JIOManager = (jclass)CJavaEnv::getInstance()->env()->NewGlobalRef( CJavaEnv::getInstance()->env()->FindClass(ioManagerName) );

    ..... some code

CJavaEnv::getInstance()->env()->DeleteGlobalRef(JIOManager);

      

but I am getting this crash:

09-21 15:38:13.259: E/dalvikvm(3210): JNI ERROR (app bug): local reference table overflow (max=512)
09-21 15:38:13.259: W/dalvikvm(3210): JNI local reference table (0x76fb50) dump:
09-21 15:38:13.259: W/dalvikvm(3210):   Last 10 entries (of 512):
09-21 15:38:13.259: W/dalvikvm(3210):       511: 0x40a609a8 java.lang.Class<libcore.icu.NativeConverter>
09-21 15:38:13.259: W/dalvikvm(3210):       510: 0x42349610 byte[] (1 elements)
09-21 15:38:13.259: W/dalvikvm(3210):       509: 0x41d866b8 java.lang.Class<com.Cocoa.CocoaAndroidSDK.CocoaUnicodeConverter>
09-21 15:38:13.259: W/dalvikvm(3210):       508: 0x423495f8 byte[] (2 elements)
09-21 15:38:13.259: W/dalvikvm(3210):       507: 0x42349428 byte[] (1 elements)
09-21 15:38:13.259: W/dalvikvm(3210):       506: 0x41d866b8 java.lang.Class<com.Cocoa.CocoaAndroidSDK.CocoaUnicodeConverter>
09-21 15:38:13.259: W/dalvikvm(3210):       505: 0x42349410 byte[] (2 elements)
09-21 15:38:13.259: W/dalvikvm(3210):       504: 0x422b3f08 byte[] (1 elements)
09-21 15:38:13.259: W/dalvikvm(3210):       503: 0x41d866b8 java.lang.Class<com.Cocoa.CocoaAndroidSDK.CocoaUnicodeConverter>
09-21 15:38:13.259: W/dalvikvm(3210):       502: 0x422b3ef0 byte[] (2 elements)
09-21 15:38:13.259: W/dalvikvm(3210):   Summary:
09-21 15:38:13.259: W/dalvikvm(3210):       172 of java.lang.Class (3 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         1 of java.lang.String
09-21 15:38:13.259: W/dalvikvm(3210):         8 of byte[] (8 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        20 of byte[] (1 elements) (20 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        27 of byte[] (2 elements) (27 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         2 of byte[] (3 elements) (2 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        16 of byte[] (4 elements) (16 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        40 of byte[] (5 elements) (40 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         2 of byte[] (6 elements) (2 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         4 of byte[] (7 elements) (4 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        22 of byte[] (8 elements) (22 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        15 of byte[] (9 elements) (15 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        40 of byte[] (10 elements) (40 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         3 of byte[] (11 elements) (3 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        17 of byte[] (12 elements) (17 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         7 of byte[] (14 elements) (7 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         8 of byte[] (15 elements) (8 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        15 of byte[] (16 elements) (15 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         8 of byte[] (17 elements) (8 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        16 of byte[] (18 elements) (16 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         3 of byte[] (21 elements) (3 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         3 of byte[] (22 elements) (3 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):        17 of byte[] (24 elements) (17 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         4 of byte[] (28 elements) (4 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         8 of byte[] (30 elements) (8 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         1 of byte[] (32 elements)
09-21 15:38:13.259: W/dalvikvm(3210):         4 of byte[] (33 elements) (4 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         8 of byte[] (34 elements) (8 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         5 of byte[] (36 elements) (5 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         2 of byte[] (41 elements) (2 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         3 of byte[] (42 elements) (3 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         1 of byte[] (56 elements)
09-21 15:38:13.259: W/dalvikvm(3210):         4 of byte[] (66 elements) (4 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         4 of byte[] (72 elements) (4 unique instances)
09-21 15:38:13.259: W/dalvikvm(3210):         2 of byte[] (82 elements) (2 unique instances)
09-21 15:38:13.259: E/dalvikvm(3210): Failed adding to JNI local ref table (has 512 entries)
09-21 15:38:13.259: I/dalvikvm(3210): "AsyncTask #2" prio=5 tid=16 RUNNABLE
09-21 15:38:13.259: I/dalvikvm(3210):   | group="main" sCount=0 dsCount=0 obj=0x41decfd8 self=0x776200
09-21 15:38:13.259: I/dalvikvm(3210):   | sysTid=3236 nice=10 sched=0/0 cgrp=bg_non_interactive handle=7541280
09-21 15:38:13.259: I/dalvikvm(3210):   | schedstat=( 0 0 0 ) utm=82 stm=70 core=1
09-21 15:38:13.259: I/dalvikvm(3210):   at libcore.icu.NativeConverter.openConverter(Native Method)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.nio.charset.CharsetEncoderICU.newInstance(CharsetEncoderICU.java:71)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.nio.charset.CharsetICU.newEncoder(CharsetICU.java:27)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.nio.charset.Charset.encode(Charset.java:451)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.lang.String.getBytes(String.java:870)
09-21 15:38:13.259: I/dalvikvm(3210):   at com.Cocoa.CocoaAndroidSDK.CocoaUnicodeConverter.UTF8_TO_UTF16(CocoaUnicodeConverter.java:16)
09-21 15:38:13.259: I/dalvikvm(3210):   at com.Cocoa.CocoaAndroidSDK.CocoaSDKNativeLib.load(Native Method)
09-21 15:38:13.259: I/dalvikvm(3210):   at com.Cocoa.CocoaViewer.MainActivity$LongOperation.doInBackground(MainActivity.java:1498)
09-21 15:38:13.259: I/dalvikvm(3210):   at com.Cocoa.CocoaViewer.MainActivity$LongOperation.doInBackground(MainActivity.java:1)
09-21 15:38:13.259: I/dalvikvm(3210):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
09-21 15:38:13.259: I/dalvikvm(3210):   at java.lang.Thread.run(Thread.java:856)
09-21 15:38:13.259: E/dalvikvm(3210): VM aborting
09-21 15:38:13.259: A/libc(3210): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)

      

Any help is appreciated.

+1


source to share


2 answers


The "other" thread must also be attached for use JIOManager

. Why not get a local link there too? On the other hand, your crash dump assumes that you are really only looking at 3 grades. This way, you can create global references to them once (even JNI_OnLoad()

if it's easier for you), and use them from all your own streams.



+2


source


There is a limit on the number of local links per stream and you are exceeding it. The most common way to do this is to create local references in a loop rather than deleting them along the way.

Local references are cleared automatically (and almost instantly) when execution returns to the VM, so for simple purposes it is best to just let the VM do the job. However, if you create more than 16 local links, it is recommended that you clean up manually.

The call FindClass

invokes a local reference. The call NewGlobalRef

creates a global reference without destroying the local reference. You should change your code like this:



jclass temp = CJavaEnv::getInstance()->env()->FindClass(ioManagerName);
jclass JIOManager = (jclass)CJavaEnv::getInstance()->env()->NewGlobalRef(temp);
CJavaEnv::getInstance()->env()->DeleteLocalRef(temp);

      

Global references are not destroyed unless you explicitly destroy them, so be careful about leaking them. When CheckJNI is on, the cap is several thousand; without CheckJNI they are allowed to accumulate without restrictions.

See also JNI Tips .

+2


source







All Articles