Использование памяти объекта Java - IBM JVM 1.4.2 - PullRequest
4 голосов
/ 19 октября 2010

Можно ли найти использование памяти объекта в Java внутри приложения?

Я хочу, чтобы использование памяти объекта было частью вывода отладочной информации при запуске приложения.Я не хочу подключаться с помощью внешнего приложения к ВМ.

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

РЕДАКТИРОВАТЬ: Я использую Java 1.4: /

Ответы [ 4 ]

6 голосов
/ 19 октября 2010

Смотрите мой любимый проект, MemoryMeasurer . Небольшой пример:

long memory = MemoryMeasurer.measureBytes(new HashMap());

Вы также можете получить более качественную разбивку памяти:

Footprint footprint = ObjectGraphMeasurer.measure(new HashMap());

Например, я использовал последний, чтобы получить на запись стоимость различных структур данных , где вместо этого измеряются накладные расходы на количество созданных объектов, ссылок и примитивов, вместо этого только байтов (что также выполнимо). Таким образом, в следующий раз, когда вы используете (по умолчанию) HashSet, вы можете быть проинформированы, что каждый элемент в нем стоит 1 новый объект (не ваш элемент), 5 ссылок и int, что является точно такой же стоимостью для записи в HashMap (не случайно, поскольку любой элемент HashSet заканчивается на HashMap) и так далее.

Вы можете использовать его на любом графе объектов. Если ваш граф объектов содержит ссылки на другие структуры, которые вы хотите игнорировать, вы должны использовать предикат, чтобы не исследовать их.

Edit Instrumentation недоступно для Java 1.4 (вау, люди все еще используют это ?!), поэтому вызов memoryBytes выше не будет работать для вас. Но второй бы. Затем вы можете написать что-то вроде этого (если вы находитесь на 32-битной машине):

long memory = footprint.getObjects() * 8 + footprint.getReferences() * 4 +
              footprint.getPrimitives().count(int.class) * 4 + 
              footprint.getPrimitives().count(long.class) * 8 + ...;

Это дает вам приближение. Лучшим ответом было бы приближение к кратному 16:

long alignedMemory = (x + 15) & (~0xF); //the last part zeros the lowest 4 bits

Но ответ все еще может быть не принят, поскольку, если вы найдете, скажем, 16 логических значений, одно дело, если они найдены в одном и том же объекте, и совсем другое, если они распределены по нескольким объектам (и вызывают чрезмерное использование пространства из-за для выравнивания). Эта логика может быть реализована как еще один посетитель (аналогично тому, как MemoryMeasurer и ObjectGraphMeasurer реализованы - довольно просто, как вы можете видеть), но я не стал беспокоиться Так как это то, что делает Instrumentation, то это будет иметь смысл только для версий Java ниже 1.5.

1 голос
/ 19 октября 2010

Eclipse MAT - действительно хороший инструмент для анализа памяти.

0 голосов
/ 19 октября 2010

Следующая ссылка предоставляет фрагмент кода Java, вычисляющий размер объектов:

http://www.javaworld.com/javaworld/javatips/jw-javatip130.html

0 голосов
/ 19 октября 2010

Существуют инструменты, поставляемые с jdk, такие как jmap и jhat, которые предоставляют сведения об уровне объекта.

...