Я пытаюсь понять, каков объем памяти объекта на Java. Я прочитал this и другие документы об объекте и памяти на Java.Объект памяти объекта Java - измерение Visualvm и java.sizeOf
Однако, когда я использую sizeof Java library или visualvm, я получаю два разных результата, в которых ни одна из них не может быть ожидаемой в соответствии с предыдущей ссылкой (http://www.javamex.com).
Для моего теста я использую Java SE 7 Developer Preview
на 64-bits Mac
с java.sizeof 0.2.1
и visualvm 1.3.5
.
У меня есть три класса, TestObject
, TestObject2
, TestObject3
.
public class TestObject
{
}
public class TestObject2 extends TestObject
{
int a = 3;
}
public class TestObject3 extends TestObject2
{
int b = 4;
int c = 5;
}
Мой главный класс:
public class memoryTester
{
public static void main(String[] args) throws Throwable
{
TestObject object1 = new TestObject();
TestObject2 object2 = new TestObject2();
TestObject3 object3 = new TestObject3();
int sum = object2.a + object3.b + object3.c;
System.out.println(sum);
SizeOf.turnOnDebug();
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object1)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object2)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object3)));
}
}
С java.SizeOf() я получаю:
{ test.TestObject
} size = 16.0b
16.0b
{ test.TestObject2
a = 3
} size = 16.0b
16.0b
{ test.TestObject3
b = 4
c = 5
} size = 24.0b
24.0b
С VisualVM у меня есть:
this (Java frame) TestObject #1 16
this (Java frame) TestObject2 #1 20
this (Java frame) TestObject3 #1 28
Согласно документаций I читать через Интернет, поскольку я в 64-битных, я должен имеют заголовок объекта 16 байт, ok для TestObject
.
Затем для TestObject2
Я должен добавить 4 байта для целочисленного поля, дающего 20 байтов, я должен добавить еще 4 байта заполнения, давая общий размер 24 байта для TestObject2
. Я ошибаюсь?
Продолжая этот путь для TestObject3
, я должен добавить еще 8 байтов для двух целых полей, которые должны дать 32 байта.
VisualVm, кажется, игнорирует прокладку, тогда как java.sizeOf, кажется, пропускает 4 байта, как если бы они были включены в заголовок объекта. Я могу заменить целое число на 4 булевых, он дает тот же результат.
Вопросы:
Почему эти два инструмента дают разные результаты?
Должны ли мы иметь прокладку?
Я также где-то читал (я не нашел ссылку), что между классом и его подклассом может быть какое-то дополнение, верно? В этом случае унаследованное дерево классов может иметь некоторые издержки памяти?
И, наконец, есть ли какой-либо Java spec/doc, который детализирует, что делает Java?
Благодарим за помощь.
Update:
Чтобы ответить на комментарий от utapyngo, чтобы получить размер объектов в VisualVM, я создаю heapdump, а затем в «классах» часть I в столбце «размер» следующий после столбец «экземпляры». Количество экземпляров, если 1 для каждого типа объектов.
Чтобы ответить на комментарий Натаниэля Форда, я инициализировал каждого бойца, а затем сделал простую сумму с ними в моем основном методе, чтобы использовать их. Это не изменило результаты.
У нас нет способа узнать, что правильно, если они не видят своей логики, как они измеряют потребление памяти. –
В моем случае jvisualvm 1.7.0 (Build 110325) на 64-битной Java 1.7.0-b147 дает 16, 16 и 24. Какой метод вы используете для измерения с помощью visualvm? – utapyngo
Возможно, вам не удастся получить точные результаты без присвоения значения полям-членам 'a',' b' и 'c'. В основе реализации JVM может не потребоваться фактическое выделение памяти для не используемых полей, а выделение памяти для хранения указателей на эти поля. –