puntero - ¿Cómo puedo obtener la ubicación de memoria de un objeto en Java?
obtener direccion de memoria en java (4)
Quiero saber la ubicación que JVM asigna a los objetos que se colocan en la memoria del sistema.
Quiero saber la ubicación que JVM asigna a los objetos
No puedes, porque no existe. Cambia con el tiempo debido a la acción del recolector de basura. No existe tal cosa como '' la ubicación''.
Esto es algo que probablemente no quieras hacer.
Si realmente quieres hacer esto, algo como este código podría ayudar:
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();
}
}
Pero
- no portátil a través de JVM o incluso versiones diferentes
- los objetos pueden moverse debido a GC en cualquier momento, y no se pueden sincronizar a través de los GC, por lo que los resultados pueden no tener sentido
- no probado en todas las arquitecturas, endianess, etc. podría hacer que esto no funcione en todas partes
Puede usar http://openjdk.java.net/projects/code-tools/jol para analizar diseños de objetos. Para un objeto puedes usar:
System.out.println(
GraphLayout.parseInstance(someObject).toPrintable());
Sin el uso de características específicas de JVM, esto no se puede hacer. Java oculta deliberadamente la ubicación asociada a cada objeto para darle más flexibilidad a la implementación (la JVM a menudo mueve los objetos en la memoria cuando realiza la recolección de elementos no utilizados) y para mejorar la seguridad (no puede usar punteros sin procesar para destruir la memoria o acceder a objetos inexistentes).