Java - требует ли пустая переменная места в памяти - PullRequest
61 голосов
/ 12 марта 2010
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. Сколько места занимает строка в памяти. Я думаю, это будет зависеть от длины строки. Так сколько места занимает строка длины?

Ответы [ 4 ]

54 голосов
/ 12 марта 2010

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

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

11 голосов
/ 05 ноября 2012

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

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

    Object s = (String) null;

    Object i = (Integer) null;

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

4 голосов
/ 13 мая 2015

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

Я использую версию 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). (И если у вас есть несколько экземпляров всех из них, это зависит от того, используете ли вы один и тот же несколько раз или разные). Нулевое поле не может быть пропущено в памяти, так как для него потребуется изменить размер экземпляра при его назначении. Таким образом, все поля предварительно созданы, они просто не ссылаются на выделенные объекты где-то еще в куче.

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

0 голосов
/ 07 июня 2018

Ноль означает 0. Обычно в памяти определено одно нулевое место. Всякий раз, когда кто-то указывает на это, используя язык программирования. Все указывает на то же место. Это означает, что для NULL используется только одна 4-байтовая память. Тогда все, что указывает на это, не потребляет больше памяти. Определение NULL зависит от языка, но его определение void * ptr = 0; распространен в C и C ++. JAVA, должно быть, определил это аналогично. Невозможно указать ни на что из. Вы должны указать на что-то. Но мы определяем общее ничто, и все указывает на то, что оно потребляет только это пространство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...