Смотрите мой любимый проект, 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.