Good stuff. Here is a useful article with more on the topic in case anyone else is interested. Includes links to other useful articles at other sites (e.g. Mechanical Sympathy) too.
http://psy-lob-saw.blogspot.com/2013/05/know-thy-java-object-memory-layout.html Shane ----- Original Message ----- From: "Sanne Grinovero" <[email protected]> To: "infinispan -Dev List" <[email protected]> Sent: Thursday, November 14, 2013 3:18:08 PM Subject: [infinispan-dev] Cost of inheritance In a particular benchmark I'm running, the bottleneck of my system seems to be the object allocation rate. More specifically, in just some minutes I've got about 55GB allocated just of instances of SingleKeyNonTxInvocationContext (yes I literally mean GigaBytes) and 45GB of org.infinispan.commands.read.GetKeyValueCommand. To be clear: these high amounts are caused only by the "shallow" class instance of these two types, not counting key nor value sizes being actually moved into/out Infinispan. Of course it means we're talking about many of these instances, but also the size of each of them matters, so I've been taking a look at their definitions. Running 64-bit HotSpot VM. Using compressed references with 3-bit shift. Objects are 8 bytes aligned. # org.infinispan.context.SingleKeyNonTxInvocationContext offset size type description 0 12 (assumed to be the object header + first field alignment) 12 1 byte AbstractInvocationContext.contextFlags 13 3 (alignment/padding gap) 16 4 Address AbstractInvocationContext.origin 20 4 WeakReference AbstractInvocationContext.classLoader 24 1 boolean SingleKeyNonTxInvocationContext.isOriginLocal 25 1 boolean SingleKeyNonTxInvocationContext.isLocked 26 2 (alignment/padding gap) 28 4 Object SingleKeyNonTxInvocationContext.key 32 4 CacheEntry SingleKeyNonTxInvocationContext.cacheEntry 36 4 (loss due to the next object alignment) 40 (object boundary, size estimate) I notice two things in here: a) we could refactor maybe some code to have less fields in such a hot allocated type b) Lots of space is being wasted in padding! If you count the bytes lost because of the various alignment rules: 9 That's almost 25%, about 13GB of used memory! Why are there two separate object alignment gaps? That's because the fields of the parent class need to be grouped, then the child class's fields are aligned after it. In other words, if I move the fields from the parent class to the bottom class I get: org.infinispan.context.SingleKeyNonTxInvocationContext offset size type description 0 12 (assumed to be the object header + first field alignment) 12 1 byte SingleKeyNonTxInvocationContext.contextFlags 13 1 boolean SingleKeyNonTxInvocationContext.isOriginLocal 14 1 boolean SingleKeyNonTxInvocationContext.isLocked 15 1 (alignment/padding gap) 16 4 Address SingleKeyNonTxInvocationContext.origin 20 4 ClassLoader SingleKeyNonTxInvocationContext.classLoader 24 4 Object SingleKeyNonTxInvocationContext.key 28 4 CacheEntry SingleKeyNonTxInvocationContext.cacheEntry 32 (object boundary, size estimate) which recovers 20% .. Looking forward to see simpler class hierarchies in the code ;-) Sanne _______________________________________________ infinispan-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/infinispan-dev _______________________________________________ infinispan-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/infinispan-dev
