Rekurzivní sizeOf pro JVM
Při svém tažení za porozuměním jak JVM pracuje s pamětí jsem si napsal jednoduchý program, který rekurzivně spočítá velikost objektu a všech jeho komponent.
Když chci zjistit velikost instance Vectoru obsahujícího 500 elementů, udělám to jednoduše:
val vect = scala.collection.immutable.Vector(1 to 500: _*) SizeOf.sizeOfStats(vect)
Výstupem pak bude něco ve smyslu:
total 10504 java.lang.Integer 12 java.lang.Integer.value: int 16 scala.collection.immutable.Vector 12 scala.collection.immutable.Vector.startIndex: int 16 scala.collection.immutable.Vector.endIndex: int 20 scala.collection.immutable.Vector.focus: int 24 scala.collection.immutable.Vector.depth: int 28 scala.collection.immutable.Vector.dirty: boolean 32 scala.collection.immutable.Vector.display0: [Ljava.lang.Object; 36 scala.collection.immutable.Vector.display1: [Ljava.lang.Object; 40 scala.collection.immutable.Vector.display2: [Ljava.lang.Object; 44 scala.collection.immutable.Vector.display3: [Ljava.lang.Object; 48 scala.collection.immutable.Vector.display4: [Ljava.lang.Object; 52 scala.collection.immutable.Vector.display5: [Ljava.lang.Object; 56 count one sum ---------------------------- 17 144B 2448B [Ljava.lang.Object; 500 16B 8000B java.lang.Integer 1 56B 56B scala.collection.immutable.Vector ---------------------------- 518 72B 10504B
Z výstupu je patrné několik věcí:
- Celková velikost objektu je 10504 bajtů.
- Při procházení objektového grafu program narazil na třídy
Integer
aVector
. Integer má jeden atributvalue
typu int na offsetu 12 a celková velikost třídy je 16 bajtů. Vector má 11 atributů: inty, boolean a pole objektů. - Celkem prošel 17 polí objektů (jedno v průměru zabíralo 144 bajtů a v součtu 2448 bajtů), 500 objektů Integer a 1 objekt Vector.
- Dohromady viděl 518 objektů, jeden měl v průměru 72 bajtů a dohromady zabraly oněch 10504 bajtů.
Nedostanu tedy jenom jedno číslo, ale i pohled pod kapotu, z čeho je objekt
složen uvnitř. Program si poradí s cyklickým objektovým grafem. Jednotlivé
objekty od sebe rozlišuje pomocí jejich identityHashCode
. To sice není
unikátní, ale pro rozumně malé objekty se dá počítat s tím, že výsledek bude
přesný.
Příště s tímhle udělátkem provedu několik měření, jak jsou na tom kolekce s hladem po paměti.
Zdrojové kódy jsou dostupné na githubu.