Автор оригинала: 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 .