размер Java-объекта

Как мы можем узнать размер объекта Java??

Пример:

class Person{
    String name;  
    int age;  

    public Person(String n, int a){  
        name = n;  
        age = a;  
    }
}  

Person person = new Person("Andy", 30);  

теперь, как я могу узнать размер объекта человека ??

Спасибо


person daydreamer    schedule 06.11.2010    source источник
comment
Зачем нужно знать размер объекта?   -  person Oliver Charlesworth    schedule 07.11.2010
comment
Если вам действительно нужно знать... stackoverflow.com/questions/52353/   -  person robert_x44    schedule 07.11.2010
comment
рассмотрим сценарий, в котором у нас ограниченная память, а в приложении есть несколько объектов, занимающих место, как мы тогда определяем, какой объект занимает больше места, и обрабатываем его соответствующим образом.   -  person daydreamer    schedule 07.11.2010
comment
ограниченная память может быть где угодно, возможно, мой рабочий стол/ноутбук по отношению к приложению, которое я запускаю   -  person daydreamer    schedule 07.11.2010
comment
@leaner, я могу сказать вам, что эта структура данных крошечная для рабочего стола. Такой маленький, что не стоит об этом беспокоиться.   -  person Peter Lawrey    schedule 07.11.2010


Ответы (6)


Вопрос не имеет смысла, по крайней мере, без дополнительного контекста.

Понятие «размер» в Java достаточно хорошо определено только для примитивов: байт — это 8 бит (что неудивительно), int — 32 бита, long — 64 бита и т. д. (см., например, http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html для полного список).

Для экземпляров объектов это сложнее, потому что:

  • Экземпляры объекта могут (и обычно будут) содержать внутренние ссылки на другие экземпляры, поэтому вы должны решить, следует ли учитывать эти зависимые экземпляры и как. Что делать, если несколько экземпляров имеют общую зависимость?
  • Иногда экземпляры объекта могут использоваться повторно (например, интернирование java.lang.String, см. http://en.wikipedia.org/wiki/String_interning ). Поэтому, если вы используете x объектов размера y, общий размер может быть меньше, чем x * y.
  • У JVM есть много возможностей для внутренней реализации объектов и экземпляров. Он может использовать разные методы для разных экземпляров (например, совместное использование внутренних структур данных), поэтому может даже не быть значимого «размера» для назначения одному объекту.

Может быть, вы могли бы объяснить, почему вас интересуют размеры объектов.

Есть несколько эмпирических правил для оценки памяти кучи, используемой экземплярами (например, в Sun JVM экземпляр java.lang.Object использует 8 байт), но они будут зависеть от используемой вами JVM.

Как правило, если вы хотите узнать об использовании кучи, используйте профилировщик памяти/кучи.

Изменить:

Ну, есть (начиная с JDK 6) способ получить приблизительное количество памяти, используемой объектом: http://download.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

Это пока только приблизительно...

person sleske    schedule 06.11.2010

Я думаю, вы можете получить что-то, что может вам помочь, если вы сделаете что-то вроде этого:

    /* First trigger classloading */
    MyObject delegate = new MyObject();

    Runtime.getRuntime().gc();

    long before = Runtime.getRuntime().freeMemory();
    MyObject delegate2 = new MyObject();
    long after = Runtime.getRuntime().freeMemory();

    System.out.println("Memory used:"+(before-after));

Мы надеемся, что это даст вам ответ, который вы хотите, или, по крайней мере, приближение.

person Knubo    schedule 06.11.2010
comment
А как насчет многопоточных ситуаций? Если два объекта одинакового размера выделяются одновременно, то значение используемой памяти будет в два раза больше требуемого размера. - person Richard J. Ross III; 07.11.2010
comment
Я бы сделал небольшой контролируемый тест для объектов, которые я хочу проверить. Если вы делаете это в многопоточной среде, то все ставки отключены. - person Knubo; 07.11.2010

EhCache предоставляет класс SizeOf, который попытается использовать Агент Instrumentation и вернется к другой подход, если агент не загружен или не может быть загружен (подробности здесь ).

См. также агент от Heinz Kabutz.

person sourcedelica    schedule 22.04.2013

Вы можете использовать библиотеку sizeof4j для вычисления размера любого объекта в java, например SizeOf.shallowSize(new Integer(2))

person Artur Mkrtchyan    schedule 03.12.2014

Объекты. Чтобы определить использование памяти объектом, мы добавляем объем памяти, используемый каждой переменной экземпляра, к накладным расходам, связанным с каждым объектом, обычно 16 байт. Накладные расходы включают ссылку на класс объекта, информацию о сборке мусора и информацию о синхронизации. Кроме того, использование памяти обычно дополняется до кратного 8 байтам (машинным словам на 64-битной машине). Например, объект Integer использует 24 байта (16 байтов служебных данных, 4 байта для его переменной экземпляра int и 4 байта заполнения).

Ссылка: https://rads.stackoverflow.com/amzn/click/com/032157351X

person daydreamer    schedule 14.08.2012

В Java нет встроенного оператора sizeof.

Вы можете попробовать использовать метод сериализации, сериализовав объект в память и получив размер этих данных, но это не обязательно будет тот размер, который вам нужен.

У вас также может быть метод с именем sizeOf(), например:

// returns the size of this object in bytes
int sizeOf()
{
     int size = 0;
     size += name.Length * 2; // each character in name is 2 bytes, no?
     size += 4; // for n, which is 32 bits = 4 bytes
}

Обратите внимание, что эта реализация не включает метаданные внутри имени, а только количество байтов, необходимое для создания для него char[].

person Richard J. Ross III    schedule 06.11.2010
comment
Но также это не покажет, сколько места занимают заголовки или около того. - person thejh; 07.11.2010
comment
Отредактировано, я добавил эту информацию... честно говоря, я не думаю, что Java когда-либо предназначалась для такой функции... - person Richard J. Ross III; 07.11.2010
comment
Я считаю, что сериализация не является точным способом сделать это, поскольку она добавляет метаданные с объектами, чтобы процесс десериализации знал, как реконструировать объект. - person daydreamer; 07.11.2010
comment
Правильный. Второй способ более точный, но все же зачем вам знать размер объекта.. похож ли этот размер на C/C++ sizeof? - person Richard J. Ross III; 07.11.2010
comment
@Richard, я понятия не имею, RD только что дал одну ссылку выше, проверьте это, это кажется хорошим! - person daydreamer; 07.11.2010
comment
Размер сериализованного объекта может сильно отличаться от памяти, используемой экземпляром объекта. Строка, например. сериализованные с использованием кодировки UTF-8, но в памяти, экземпляры String внутренне используют UTF-16 (по крайней мере, в виртуальной машине Oracle). - person jarnbjo; 07.11.2010
comment
Я сказал это в своем ответе :) да, это не идеально, но я не думаю, что Java действительно предназначалась для такой функции. - person Richard J. Ross III; 07.11.2010