Я хочу знать местоположение, которое JVM выделяет для объектов, помещенных в системную память.
Как я могу получить местоположение памяти объекта в java?
Ответ 1
Это то, что вы, вероятно, не хотите делать.
Если вы действительно хотите это сделать, что-то вроде этого кода может помочь:
package test;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Addresser
{
private static Unsafe unsafe;
static
{
try
{
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static long addressOf(Object o)
throws Exception
{
Object[] array = new Object[] {o};
long baseOffset = unsafe.arrayBaseOffset(Object[].class);
int addressSize = unsafe.addressSize();
long objectAddress;
switch (addressSize)
{
case 4:
objectAddress = unsafe.getInt(array, baseOffset);
break;
case 8:
objectAddress = unsafe.getLong(array, baseOffset);
break;
default:
throw new Error("unsupported address size: " + addressSize);
}
return(objectAddress);
}
public static void main(String... args)
throws Exception
{
Object mine = "Hi there".toCharArray();
long address = addressOf(mine);
System.out.println("Addess: " + address);
//Verify address works - should see the characters in the array in the output
printBytes(address, 27);
}
public static void printBytes(long objectAddress, int num)
{
for (long i = 0; i < num; i++)
{
int cur = unsafe.getByte(objectAddress + i);
System.out.print((char)cur);
}
System.out.println();
}
}
Но
- не переносится через JVM или даже разные версии
- объекты могут перемещаться из-за GC в любое время и не могут синхронизироваться через GC, поэтому результаты могут не иметь смысла.
- не проверен на всех архитектурах, endianess и т.д., возможно, это не работает везде.
Ответ 2
Без использования JVM-специфических функций это невозможно. Java намеренно скрывает местоположение, связанное с каждым объектом, чтобы обеспечить реализацию большей гибкости (JVM часто перемещает объекты вокруг в памяти при сборке мусора) и для повышения безопасности (вы не можете использовать необработанные указатели для извлечения памяти или доступа к несуществующим объектам).
Ответ 3
Вы можете использовать http://openjdk.java.net/projects/code-tools/jol для анализа макетов объектов. Для одного объекта вы можете использовать:
System.out.println(
GraphLayout.parseInstance(someObject).toPrintable());
Ответ 4
Я хочу знать местоположение, которое JVM выделяет для объектов
Вы не можете, потому что его не существует. Он изменяется со временем из-за действия сборщика мусора. Нет такой вещи, как "местоположение".