Подтвердить что ты не робот

Java - Нулевая переменная требует пространства в памяти

class CheckStore {
    private String displayText;
    private boolean state;
    private String meaningfulText;
    private URL url;

    public CheckStore(String text, boolean state) {
        this.displayText = text;
        this.state = state;
    }
    :
    :
}

Поскольку я инициализирую в конструкторе только две переменные (displayText и state), оставшиеся две переменные (meaningfulText и url, которые будут иметь значение null), потребуют пространства в памяти для сохранения значения null.

Q1. Думаю, им потребуется пространство. Если да, то сколько памяти занимает значение null в памяти (например, int занимает 4 байта).

Q2. Сколько пространства занимает строка в памяти. Думаю, это будет зависеть от длины строки. Итак, сколько места занимает строка, сколько длины?

4b9b3361

Ответ 1

В Java null - это просто значение, которое может иметь ссылка (которая в основном ограничена указателем). Это означает, что ссылка ссылается на ничего. В этом случае вы все еще занимаете пространство для ссылки. Это 4 байта в 32-битных системах или 8 байтах в 64-битных системах. Однако вы не занимаете места для класса, на который ссылается ссылка, пока вы фактически не выделите экземпляр этого класса для указания ссылки.

Изменить. Что касается String, a String в Java занимает 16 бит (2 байта) для каждого символа, а также небольшую часть служебных данных, которые, вероятно, недокументированы и специфичны для реализации.

Ответ 2

Я бы хотел добавить:

  • переменная ссылочного типа будет инициализирована как нулевое значение.
  • null не является объектом. потому что (null instanceof Object) равен false
  • в JVM имеется только одно значение null. Независимо от того, сколько переменных ссылается на null.

    Объект s = (String) null;

    Объект я = (целочисленный) null;

    System.out.println(s == i);//true

Ответ 3

Вы можете использовать jol, чтобы получить макет этого класса. (Однако будьте осторожны, вам может потребоваться более глубокое понимание механики позади него, не слепо доверять результату и быть в курсе, что это всего лишь оценка для используемой в настоящее время виртуальной машины (1.7.0_76 x64 выигрыш в моем случае:):

Я использую версию CLI. Я полагаю, что правильным методом будет включение библиотеки в ваш проект, но в любом случае, похоже, она работает следующим образом:

test>java -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore
Running 64-bit HotSpot VM.
Using compressed oop with 0-bit shift.
Using compressed klass with 0-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

VM fails to invoke the default constructor, falling back to class-only introspection.

test.CheckStore object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
      0    12         (object header)                N/A
     12     1 boolean CheckStore.state               N/A
     13     3         (alignment/padding gap)        N/A
     16     4  String CheckStore.displayText         N/A
     20     4  String CheckStore.meaningfulText      N/A
     24     4     URL CheckStore.url                 N/A
     28     4         (loss due to the next object alignment)
Instance size: 32 bytes (estimated, the sample instance is not available)
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total

и то же самое с автоматическим сжатием oops off:

test>java -XX:-UseCompressedOops -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore
Running 64-bit HotSpot VM.
Objects are 8 bytes aligned.
Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

VM fails to invoke the default constructor, falling back to class-only  introspection.

test.CheckStore object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
      0    16         (object header)                N/A
     16     1 boolean CheckStore.state               N/A
     17     7         (alignment/padding gap)        N/A
     24     8  String CheckStore.displayText         N/A
     32     8  String CheckStore.meaningfulText      N/A
     40     8     URL CheckStore.url                 N/A
Instance size: 48 bytes (estimated, the sample instance is not available)
Space losses: 7 bytes internal + 0 bytes external = 7 bytes total

Это только макеты для самого объекта, если ваши поля имеют нулевое значение, тогда он не будет указывать на большее количество объектов, в противном случае вы должны посмотреть на целевые типы (URL и String). (И если у вас есть несколько экземпляров всех из них, это зависит, если вы используете одни и те же несколько раз или разные). Пустое поле не может быть пропущено в памяти, так как это потребует изменения размера экземпляра при его назначении. Итак, все поля предварительно сконструированы, они просто не ссылаются на выделенные объекты где-то еще на куче.

NB: вы получите более подробную информацию, если вы реализуете конструктор по умолчанию, но размер в этом конкретном случае будет таким же. В случае, если вы задаетесь вопросом, откуда идет последовательность и заполнение полей, вы можете проверить эту статью - (в основном он выравнивает объекты по 8 байтам, сортирует поля по размеру, группы одного типа вместе, ссылки последние. Сначала поля из супер-типов, выровнены по 4 байт.)