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

1. Общ преглед

В този бърз урок ще видим как да намерим адреса на паметта на обектите в Java.

Преди да продължите по-нататък, струва си да споменете, че оформлението на паметта на областите с данни по време на изпълнение не е част от спецификацията на JVM и е оставено на преценката на реализатора. Следователно, всяка реализация на JVM може да има различна стратегия за оформление на обекти и масиви в паметта. Това от своя страна ще повлияе на адресите на паметта.

В този урок ние се фокусираме върху една специфична реализация на JVM: HotSpot JVM. Също така можем да използваме термините JVM и HotSpot JVM взаимозаменяемо в целия урок.

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

За да намерим адреса на паметта на обектите в JVM, ще използваме инструмента Java Object Layout (JOL). Следователно трябва да добавим зависимостта на jol-core :

 org.openjdk.jol jol-core 0.10 

3. Адрес на паметта

За да намерим адреса на паметта на определен обект в JVM, можем да използваме метода addressOf () :

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

Това ще отпечата:

The memory address is 31864981224

В HotSpot JVM има различни компресирани референтни режими. Поради тези режими тази стойност може да не е напълно точна. Следователно, не бива да ходим и да извършваме някои манипулации на естествената памет въз основа на този адрес, тъй като това може да причини странни корупции на паметта.

Също така адресите на паметта в повечето реализации на JVM подлежат на промяна, тъй като GC премества обектите от време на време.

4. Код за хеширане на самоличността

Има често срещано погрешно схващане, че адресите на паметта на обектите в JVM са представени като част от техните реализации по подразбиране toString , като [имейл защитен] . Тоест, мнозина смятат, че “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.