Ответ
Размер в памяти складывается из самой ссылки и объекта, на который она указывает. Точный размер зависит от JVM, версии Java и платформы.
1. Размер ссылки (переменной):
- Обычно 4 байта (32-битная JVM) или 8 байт (64-битная JVM).
- В современных 64-битных JVM часто используется технология Compressed Oops (обычно включена по умолчанию), которая «сжимает» ссылки до 4 байт для кучи до ~32 ГБ, что экономит память.
2. Размер объекта в куче: Минимальный размер объекта включает:
- Заголовок объекта (object header): Обычно 12 байт (8 байт для марк-слова + 4 байта для ссылки на класс). При включенных Compressed Oops. Без них — 16 байт.
- Поля объекта: Примитивные типы (
int– 4 байта,long– 8 и т.д.) и ссылки на другие объекты (по правилам из пункта 1). - Выравнивание (padding): JVM выравнивает размер объекта до кратного 8 байт для оптимизации доступа.
Пример оценки:
class SimpleObject {
private int id; // 4 байта
private String name; // ссылка: 4 байта (с Compressed Oops)
}
// Примерный расчет размера экземпляра SimpleObject:
// Заголовок: 12 байт
// Поле int id: 4 байта
// Поле-ссылка String name: 4 байта
// ИТОГО: 20 байт -> Выравнивание до 24 байт.
Как измерить точно (для отладки):
Используйте инструментальный API java.lang.instrument.Instrumentation.
import java.lang.instrument.Instrumentation;
public class SizeAgent {
private static Instrumentation inst;
// Агент должен быть собран в JAR с premain-методом
public static void premain(String args, Instrumentation instArg) {
inst = instArg;
}
public static long getObjectSize(Object o) {
return inst.getObjectSize(o);
}
}
// Вызов getObjectSize() вернет размер объекта + заголовок, но без учета вложенных объектов.
Для массивов: К базовому размеру объекта добавляется 4 байта для хранения длины и память для каждого элемента.