Рубрики
Без рубрики

Адрес памяти объектов в Java

Узнайте, как найти адрес памяти объектов в Java

Автор оригинала: Ali Dehghani.

1. Обзор

В этом кратком руководстве мы рассмотрим, как найти адрес памяти объектов в Java.

Прежде чем идти дальше, стоит упомянуть, что расположение областей данных среды выполнения в памяти не является частью спецификации JVM и оставлено на усмотрение разработчика . Поэтому каждая реализация JVM может иметь различную стратегию размещения объектов и массивов в памяти. Это, в свою очередь, повлияет на адреса памяти.

В этом уроке мы сосредоточимся на одной конкретной реализации JVM: JVM HotSpot. Мы также можем использовать термины JVM и HotSpot JVM взаимозаменяемо на протяжении всего урока.

2. Зависимость

Чтобы найти адрес памяти объектов в JVM, мы будем использовать инструмент компоновки объектов Java ( JOL ). Поэтому нам нужно добавить зависимость jol-core :

 
    org.openjdk.jol 
    jol-core    
    0.10 

3. Адрес памяти

Чтобы найти адрес памяти конкретного объекта в JVM, мы можем использовать адрес метода() :

String answer = "42";

System.out.println("The memory address is " + VM.current().addressOf(answer));

Это приведет к печати:

The memory address is 31864981224

В JVM HotSpot существуют различные сжатые опорные режимы . Из-за этих режимов это значение может быть не совсем точным. Поэтому мы не должны идти и выполнять некоторые собственные манипуляции с памятью на основе этого адреса, так как это может привести к странным повреждениям памяти.

Кроме того, адреса памяти в большинстве реализаций JVM могут изменяться по мере того, как GC время от времени перемещает объекты.

4. Идентификационный Хэш-код

Существует распространенное заблуждение, что адреса памяти объектов в JVM представлены как часть их реализаций по умолчанию toString , таких как [email protected] . То есть многие думают, что “60addb54” является адресом памяти этого конкретного объекта.

Давайте проверим это предположение:

Object obj = new Object();

System.out.println("Memory address: " + VM.current().addressOf(obj));
System.out.println("toString: " + obj);
System.out.println("hashCode: " + obj.hashCode());
System.out.println("hashCode: " + System.identityHashCode(obj));

При этом будет выведено следующее:

Memory address: 31879960584
toString: [email protected]
hashCode: 1622006612
hashCode: 1622006612

Довольно интересно, что “60addb54” является шестнадцатеричной версией хэш-кода, который равен 1622006612. Метод hashCode() является одним из общих методов для всех объектов Java. Когда мы не объявляем метод hashCode() для класса, Java будет использовать для него хэш-код идентификатора.

Как показано выше, идентификационный хэш-код (эта часть после @ в toString ) и адрес памяти отличаются .

5. Заключение

В этом коротком уроке мы рассмотрели, как найти адрес памяти объектов в Java.

Как обычно, все примеры доступны на GitHub .