Может ли JVM оптимизировать память, необходимую для ссылок на null, экземпляр нулевого типа?

Всем доброго дня,

У меня есть класс, который выглядит так:

public class Grapheme {
    public Grapheme(int[] code_points) {
        this.code_points = code_points;
    }
    int[] code_points;
}

Из ссылки, предоставленной bdonlan ниже, я понимаю, что обычно для объекта Grapheme требуется 8 байтов для заголовка объекта, 4 байта для переменной code_points (тип которой ссылка) и 4 байта заполнения.

Поэтому, если я создам экземпляр Grapheme, используя код new Grapheme(null), этот экземпляр Grapheme обычно потребует в общей сложности 16 байтов. Поскольку 16 байт или нет, зависит от реализации, с этого момента я буду называть это число как x байт.

В основном мне было интересно, создаю ли я n количество графем, передавая null в конструктор Grapheme(int[]) для всех из них, и сохраняю эти графемы в массиве длины n,

Будет ли общая память, необходимая среде выполнения (для хранения экземпляров Grapheme), составлять строго n * x байт?

Или есть какой-либо шанс, что JVM может попытаться сделать некоторые волшебные оптимизации, чтобы требуемая память была меньше n * x байт?


person Pacerier    schedule 30.01.2012    source источник


Ответы (1)


Нет. Размер объекта фиксирован. Подумайте: если JVM упаковала ваши Graphemes в массив без пробелов между ними, что произойдет, если какой-то код позже изменит значение code_points? Придется перемещать все остальные графемы и переписывать любые указатели на любой из них. Это было бы ОГРОМНЫМ ударом по производительности (вам, вероятно, потребуется выполнить полный GC, чтобы переписать все эти указатели...), и было бы совершенно непостижимо для программиста, пытающегося понять, почему простое присваивание было таким медленным. Таким образом, JVM не выполняет оптимизацию такого рода.

Также обратите внимание, что ваши оценки накладных расходов немного неверны. Согласно этой странице, объекты занимают 8 байт плюс пространство для любые внутренние поля, по 12 байт. Затем это значение округляется до числа, кратного 8 байтам, поэтому ваш объект Grapheme здесь будет иметь в общей сложности 16 байтов на 32-битной платформе и JVM Hotspot. Любые указатели на объект Grapheme будут занимать дополнительное место (вероятно, 4 байта каждый). Объектам не требуется место для собственного адреса как такового; эта память принадлежит чему-то другому (например, кадру стека или другому объекту).

person bdonlan    schedule 30.01.2012
comment
Кстати, что вы подразумеваете под пространством для любых внутренних полей? Согласно странице, на которую вы ссылаетесь, не правда ли, что всего 8 (обслуживание) + 4 (ссылка на ноль)) = 12 байтов = 16 байтов после округления до ближайших 8 = 16 байтов на объект Grapheme (да мы получаем тот же результат, но работа отличается)? - person Pacerier; 30.01.2012
comment
Внутренние поля = int[] code_points. Так что наша математика такая же :) - person bdonlan; 30.01.2012