Wednesday, January 18, 2012

Measuring a Toddlers weight and Object size in heap

...And the common problem is they both need some warm up phase. Toddlers are notorious to not stay standstill and if you have one you know typically the first reading is almost always wrong. But for these naughty Kids there is a way to measure it - Hold them in your arms measure your weight with the kid and then measure yours alone and subtract it. This modelling can also be applied to when Objects need to be measured for their size in a heap. Why? Because flakiness do exist with JVMs and based on sheer observation the first reading is almost always wrong. So not being part of a JVM team how am I suppose to measure an Object size fairly accurately? By reducing the flakiness. By measuring it multiple times. By minimising the affect of chaos.
Problem: To provide an API so that it can measure the size of an Object passed to it

Solution: Clean up the JVM, measure the heap size, create multiple instances of the Object, create strong references to these instances. clean up the JVM again and measure the heap. Take a difference and divide by the total number of Objects used.

If you are looking for measuring the size of Objects in a Coherence cache then look into Coherence's MemoryCalculator APIs. This solution uses Coherence's PoF framework for serialzing and deserializing non-Serialozable Objects.

1. We need to create multiple instances of the Object passed so that strong references can be maintained to these Objects and do not let GC collect these. So make multiple instances of the passed object. How? There are multiple options -
  • If Object implements Serializable or any of Serializable types - Serialize the Object into byte array and to create an instance use this byte array to reconstruct the Object.
  • If Object is Cloneable - To create a new instance then clone the Object
  • If Object is neither Serializable nor Cloneable - Oracle Coherence provides a mechanism to serialize a non-serializable Object called Portable Object Format. PoF as it is commonly called, allows programmers to write external serializers for an Object that does not implement Serializer interface. These Serializers and the Object they serialize and deserialize can be defined in a pof configuration and loaded by a Coherence system property tangosol.pof.config. Once this is done the Object is ready to be serialized.

For the third option Coherence provides a utility in ExternalizableHelper to convert the Object into a Binary:


ConfigurablePofContext pofContext = new ConfigurablePofContext ("my-pof-config.xml");
then:
Binary binObj = ExternalizableHelper.toBinary (objToBeMeasured, pofContext);

This binObj can then be used to create new instances to make multiple strong references:
Object[] objects = new Object [1000];
Runtime runTime = Runtime.getRuntime();

for (int i = -1; i < 1000; ++i) {
     Object o = ExternalizableHelper.fromBinary(binObj, pofContext);
    // -- Reject the first object
     if (i >= 0) {
        objects[i] = o;
     } else {
            o = null;
            // -- Execute GC;
        beforeSize = runTime.totalMemory() - runTime.freeMemory();
     }
}

Execute GC again;
afterSize = runTime.totalMemory() - runTime.freeMemory();

Use the difference of (afterSize - beforSize)/1000I also found a very good implementation of "Execute Garbage Collection" from an article on the javaworld.com, that I am reproducing it here:


for (int i = 0; i < 4; ++i) {
    long m1 = runTime.totalMemory() - runTime.freeMemory();
    long m2 = Long.MAX_VALUE;
    for (int j = 0; (m1 < m2) && (j < 500): ++j) {
         runTime.runFinalization();
         runTime.gc();
         Thread.yield();
         m2 = m1;
         m1 = runTime.totalMemory() - runTime.freeMemory();
    }
}
Watching your baby's and Object's weight is critical and you know it why? Enjoy!

Monday, January 16, 2012

एक और शेर

छुआ जो आसमां तो बादल यूँ फट गए,
अरमान दिल के सब पानी में बह गए।
बूँद हज़ार बन फिर वो खो गए कहीं,
आँख के आंसू भी कहीं उसी में मिल गए।