Расчет использования памяти Java-объекта с помощью дамп кучи VisualVM не соответствует теоретическому подходу - PullRequest
0 голосов
/ 03 декабря 2018

Все, что я пришел с простым вопросом.Согласно документации по Java и многим статьям о расположении объектов памяти Java, если у нас есть класс с одной переменной int, общее потребление памяти для этого объекта будет:

  • 8 байт для заголовка
  • 4 байта для int
  • 4 байта (для округления суммы до кратности 8 байтов) = 16 всего байтов
public class Ab {        
    int b;
}

public static void main(String args[]) throws InterruptedException {
    Ab ab = new AB();  
}  

Теперь моя проблема заключается в том, что когда я использовал Visual vm и посмотрел на дамп кучи, чтобы увидеть этот теоретический подход, я заметил, что потребление памяти для этого объекта составляет 20 байт.вместо 16 ?Почему это происходит?Может кто-нибудь объяснить мне?

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Используя Java Object Layout , я получил следующий вывод:

 OFFSET  SIZE   TYPE DESCRIPTION        VALUE
      0    12        (object header)    N/A
     12     4    int Ab.b               N/A

Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

И с опцией -XX:-UseCompressedOops VM (отключить сжатые ссылки):

 OFFSET  SIZE   TYPE DESCRIPTION                                VALUE
      0    16        (object header)                            N/A
     16     4    int Ab.b                                       N/A
     20     4        (loss due to the next object alignment)

Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

Среда Java:

java version "11" 2018-09-25
Java(TM) SE Runtime Environment 18.9 (build 11+28)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11+28, mixed mode)
0 голосов
/ 03 декабря 2018

В соответствии с разделом «Расположение заголовка объекта» в документации горячей точки: https://wiki.openjdk.java.net/display/HotSpot/CompressedOops

«Заголовок объекта состоит из слова метки собственного размера, слова класса, слова длиной 32 бита (еслиобъект является массивом), 32-разрядный пробел (если это требуется правилами выравнивания), а затем ноль или более полей экземпляра, элементов массива или полей метаданных.

Таким образом, это означает, что в вашем случае это выглядитнапример:

  • 8 байт для слова метки (8 байт на 64-битных архитектурах)
  • 4 байта для слова klass (поскольку по умолчанию используются сжатые значения oops)
  • 8 байт (это место, где хранится ваше поле int)
...