Próbuję zrozumieć, jaki jest ślad pamięci obiektu w Javie. Czytam this i inne dokumenty dotyczące obiektu i pamięci w Javie.Objawy pamięci obiektów Java - Visualvm i java.sizeOf pomiar
Jednak kiedy używam VisualVM sizeof Java library lub, mam dwa różne wyniki, gdzie żaden z nich nogi, co mogę oczekiwać według poprzedniego odniesienia (http://www.javamex.com).
Dla mojego testu używam Java SE 7 Developer Preview
na 64-bits Mac
z java.sizeof 0.2.1
i visualvm 1.3.5
.
Mam trzy klasy, 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;
}
Moje główne klasy:
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)));
}
}
Z java.SizeOf() uzyskać:
{ 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
Z VisualVM mam:
this (Java frame) TestObject #1 16
this (Java frame) TestObject2 #1 20
this (Java frame) TestObject3 #1 28
Według dokumentacji ja czytaj przez Internet, ponieważ jestem w 64-bitach, powinienem mają nagłówek obiektu 16 bajtów, ok dla TestObject
.
Następnie dla TestObject2
powinienem dodać 4 bajty dla pola liczby całkowitej dając 20 bajtów, powinienem dodać jeszcze 4 bajty dopełnienia, dając całkowity rozmiar 24 bajtów dla TestObject2
. Czy się mylę?
Kontynuując w ten sposób dla TestObject3
, muszę dodać 8 bajtów więcej dla dwóch pól liczb całkowitych, które powinny dać 32 bajty.
VisualVm wydaje się ignorować dopełnienie, podczas gdy java.sizeOf wydaje się brakować 4 bajtów, tak jakby były zawarte w nagłówku obiektu. Mogę zastąpić liczbę całkowitą przez 4 wartości logiczne, co daje taki sam wynik.
Pytania:
Dlaczego te dwa narzędzia dają różne wyniki?
Czy mamy dopełnienie?
Czytałem również gdzieś (nie znalazłem linku), że między klasą a jej podklasą może być trochę dopełnienia, czy to prawda? W takim przypadku odziedziczone drzewo klas może mieć trochę pamięci narzutowej?
Wreszcie, czy jest jakiś specyfikacja/specyfikacja Java, która opisuje, co robi Java?
Dzięki za pomoc.
Aktualizacja:
Aby odpowiedzieć na komentarz z utapyngo, aby uzyskać rozmiaru obiektów w VisualVM, tworzę heapdump, a następnie w „klas” część I sprawdź kolumnę „rozmiar” następny po kolumna "instances". Liczba wystąpień 1 dla każdego rodzaju obiektów.
Aby odpowiedzieć na komentarz Nathaniela Forda, zainicjalizowałem każdą z nich, a następnie zrobiłem z nimi prostą sumę w mojej metodzie głównej, aby z nich skorzystać. To nie zmieniło wyników.
Mamy nie wiedział co jest w porządku, czy też, nie widząc ich logikę na sposób ich pomiaru zużycia pamięci. –
W moim przypadku jvisualvm 1.7.0 (build 110325) na 64-bitowym Java 1.7.0-b147 daje 16, 16 i 24. Jakie metody używasz do pomiaru z VisualVM? – utapyngo
Możesz nie uzyskiwać dokładnych wyników bez przypisywania wartości do pól elementów "a", "b" i "c". Podstawowa implementacja JVM może nie wymagać, aby faktycznie przydzielić pamięć do pól, które nie są używane, a jedynie alokować pamięć do przechowywania wskaźników do tych pól. –