Java对象地址

>tree . /F

Folder PATH listing for volume D

Volume serial number is F075-351A

└───com

    └───jx

            com_jx_Object.cpp

            com_jx_Object.hpp

            com_jx_Object.obj

            libobj.dll

            libobj.exp

            libobj.lib

            Object.class

            Object.java

            ObjectTest.java

package com.jx;

public class Object {

	private int index;
	
	public Object(int index) {
		this.index = index;
	}
	
	public int index() {
		return index;
	}
	
	public native int addr();
	
	static {
		System.loadLibrary("libobj");
	}
}
>javac com\jx\Object.java
>javah -jni -d com\jx com.jx.Object

 com_jx_Object.hpp:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jx_Object */

#ifndef _Included_com_jx_Object
#define _Included_com_jx_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jx_Object
 * Method:    addr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

com_jx_Object.cpp:

#include <stdio.h>

#include "com_jx_Object.hpp"

JNIEXPORT jint JNICALL Java_com_jx_Object_addr
  (JNIEnv *env, jobject jobj)
{
  jlong addr = reinterpret_cast<jlong>(jobj);
  printf("Java_com_jx_Object_addr.\n");
  printf("obj addr: %ld\n", jobj);
  printf("obj addr: %ld\n", &jobj);
  printf("obj addr: %ld\n", addr);

  return 0;
}
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.cpp 
>link /DLL /OUT:.\libobj.dll .\*.obj 

也可以使用以下命令一次就生成库文件

# 也可以使用以下命令一次就生成库文件:
>cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c

将生成的库文件libobj.dll放在path目录下

package com.jx;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class ObjectTest {

	public static void main(String[] args) throws Throwable {
		String libPath = System.getProperty("java.library.path");
		System.out.println(libPath);
		
		Unsafe unsafe = getUnsafe();
		
		Object obj = new Object(12345);
		Field field = Object.class.getDeclaredField("index");
		
		long addr = location(obj);
		System.out.println("obj addr: " + obj.hashCode());
		System.out.println("obj addr: " + addr);
		System.out.println("obj addr: " + unsafe.getAddress(addr));
		
		
	    long valueOffset = unsafe.objectFieldOffset(field);
	    System.out.println("index offset: " + valueOffset);
	    int value2 = unsafe.getInt(obj, valueOffset);
	    System.out.println("index: " + value2);
	    value2 = unsafe.getInt(addr + valueOffset);
	    System.out.println("index: " + value2);
		
		obj.addr();
	}

	public static long location(Object object) throws Throwable {
		Unsafe unsafe = getUnsafe();

		Object[] array = new Object[] {object};

		long baseOffset = unsafe.arrayBaseOffset(Object[].class);
		int addressSize = unsafe.addressSize();
		long location;
		switch (addressSize) {
		case 4:
			location = unsafe.getInt(array, baseOffset);
			break;
		case 8:
			location = unsafe.getLong(array, baseOffset);
			break;
		default:
			throw new Error("unsupported address size: " + addressSize);
		}
		return (location);
	}

	private static Unsafe getUnsafe() throws Throwable {
		Class unsafeClass = Unsafe.class;
		for (Field f : unsafeClass.getDeclaredFields()) {
			if ("theUnsafe".equals(f.getName())) {
				f.setAccessible(true);
				return (Unsafe) f.get(null);
			}
		}
		throw new IllegalAccessException("no declared field: theUnsafe");
	}
}

运行结果

obj addr: 5433634
obj addr: 46840104
obj addr: 695505153
index offset: 8
index: 12345
index: 12345
Java_com_jx_Object_addr.
obj addr: 10157232
obj addr: 10157172
obj addr: 10157232

 

猜你喜欢

转载自lobin.iteye.com/blog/2437111