4

Any Android JNI developer should be familiar with this wonderful message in logcat. My question is: how can I tell the VM to dump current table state? I need it for debugging purposes to make sure that native threads at exit have no outstanding local references.

Pavel P
  • 15,789
  • 11
  • 79
  • 128

3 Answers3

14

Full credit to Pavel, but I thought others might like the example code:

jclass vm_class = env->FindClass("dalvik/system/VMDebug");
jmethodID dump_mid = env->GetStaticMethodID( vm_class, "dumpReferenceTables", "()V" );
env->CallStaticVoidMethod( vm_class, dump_mid );
JonnyBoy
  • 1,555
  • 14
  • 24
6

In case somebody needs to do something similar, you can use dumpReferenceTables from dalvik.system.VMDebug

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • Did this work for you? I can't find a way to dump the reference table to the log. – refaelos Jan 14 '13 at 15:54
  • yes, it worked very well. That's why I posted it for reference in case if somebody needs to do something like that. Check docs of VMDebug, you'll need to access java code from c++ and you'll be able to dump JNi table to logcat – Pavel P Jan 14 '13 at 16:03
  • I can't find the class dalvik.system.VMDebug. Did you have to include something in your project to get it ? – refaelos Jan 14 '13 at 17:54
  • 1
    @Rafa it's not a c/c++ thing. You have to `FindClass`, then retrieve function pointers and call them from c/c++ using JNI. – Pavel P Jan 14 '13 at 18:07
  • I understand that... the thing is that i don't see this class on the Java side. I'm just trying to do that there and it fails. – refaelos Jan 14 '13 at 19:05
  • Ok. It was fixed. Thanks ! – refaelos Jan 14 '13 at 20:01
3

I try code below.it works well.

try {
    Class cls = Class.forName("android.os.Debug");
    Method method = cls.getDeclaredMethod("dumpReferenceTables");
    Constructor con= cls.getDeclaredConstructor();
    con.setAccessible(true);
    method.invoke(con.newInstance());
    //call method dumpReferenceTables of dalvik.system.VMDebug
    //to dump reference table at last.
}
catch(Exception e){
    Log.i(TAG,"exception="+e.getMessage());
}

I/art (28913): global reference table dump:

I/art (28913): Last 10 entries (of 267):

I/art (28913): 266: 0x12e340c0 java.lang.ref.WeakReference

I/art (28913): 265: 0x12e34060 java.lang.ref.WeakReference

I/art (28913): 264: 0x12e24220 java.lang.ref.WeakReference

I/art (28913): 263: 0xa1ba5000 byte[] (2710656 elements)

I/art (28913): 262: 0xa284d000 byte[] (30276 elements)

I/art (28913): 261: 0xa2855000 byte[] (19312 elements)

I/art (28913): 260: 0xa1e3b000 byte[] (6529728 elements)

I/art (28913): 259: 0x12e1ca60 android.view.accessibility.AccessibilityManager$1

I/art (28913): 258: 0x12df2c70 android.content.ContentProvider$Transport

I/art (28913): 257: 0x12ed4040 java.lang.ref.WeakReference

I/art (28913): Summary:

I/art (28913): 2 of android.opengl.EGLContext (2 unique instances)

I/art (28913): 1 of android.hardware.display.DisplayManagerGlobal$DisplayManagerCallback

I/art (28913): 223 of java.lang.Class (172 unique instances)

I/art (28913): 2 of android.opengl.EGLDisplay (2 unique instances)

I/art (28913): 2 of java.lang.ThreadGroup (2 unique instances)

I/art (28913): 2 of android.opengl.EGLSurface (2 unique instances)

I/art (28913): 1 of dalvik.system.VMRuntime

I/art (28913): 1 of android.content.ContentProvider$Transport

I/art (28913): 1 of dalvik.system.PathClassLoader

I/art (28913): 1 of android.view.accessibility.AccessibilityManager$1

I/art (28913): 1 of android.app.ActivityThread$ApplicationThread

I/art (28913): 2 of byte[] (100 elements) (2 unique instances)

I/art (28913): 7 of byte[] (8192 elements) (7 unique instances)

I/art (28913): 1 of byte[] (19312 elements)

I/art (28913): 1 of byte[] (30276 elements)

I/art (28913): 1 of byte[] (2710656 elements)

I/art (28913): 1 of byte[] (6529728 elements)

I/art (28913): 2 of java.lang.String (2 unique instances)

I/art (28913): 15 of java.lang.ref.WeakReference (15 unique instances)

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Joe Tang
  • 31
  • 1