[infinispan-dev] Cost of inheritance

Sanne Grinovero sanne at infinispan.org
Thu Nov 14 16:18:08 EST 2013


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


More information about the infinispan-dev mailing list