简体   繁体   中英

Using NDK to get an Object's pointing memory address

I'm currently on a curious trip and I'm trying to create a native method that returns the memory address of a Java Object .

I have properly configure Android's NDK and my Java method is:

public static native String getAddressOf(Object obj);

Following that, my native implementation in C:

jstring Java_com_danysantiago_andmemutil_MemoryUtils_getAddressOf(JNIEnv *env, jobject clazz, jobject obj) {
    char buffer[11];
    sprintf(buffer, "%p", obj);
    return (*env)->NewStringUTF(env, buffer);
}

But for some reason the returned string address is always the same no matter how much I play around with the app on the emulator. I'm assuming I'm not getting the actual memory pointer or my Java knowledge of how objects are stored in memory is wrong.

More Background Story: I have successfully obtained the address of an Object in a standard Java app that runs on my computer's JVM following this stackoverflow answer . I was able to confirm it because I made a heap dump and then used MAT to do a search for address which resulted in an instance of my dummy class. However, sun.misc.unsafe is not available in Android.

When I try to follow similar steps, making a heap dump of the Android app and searching for the address that the method returns I get no result, but if I use OQL , that is available with MAT I can find the instance of my dummy class with a different address.

Looking at how using unsafe one gets the address makes me wonder that in reality I too, with native code, have to calculate the address inspecting the Object fields.

Bring in your knowledge awesome people! Thanks! :)

You can't generally do that.

Dalvik used to pass the object address through JNI, but switched to indirect references in the ICS release. The motivation for doing so was to make it easier to move objects in the heap, eg for a compacting garbage collector. If app code could get the address of any object visible to JNI, then the GC wouldn't be able to move those objects around, because native code might be accessing them while the GC is running. (As of Android 4.4 KitKat, objects did not move, but I assume that will change in upcoming releases.)

I think most versions of Android will return the object address from System#identityHashCode() , avoiding the need to use JNI, but if that works now I expect it'll break soon as well.

And of course, if you did manage to get an address, it would only tell you what the address was , not what the address is , because the VM is free to relocate objects at any time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM