To blog |

How much memory do I need (part 3) – measure, don’t guess

August 28, 2012 by Nikita Salnikov-Tarnovski Filed under: Memory Leaks

What looks like as an easy task can in reality become somewhat complicated. There is a whole lot of different aspects you have to bear in mind when calculating the memory footprint of your objects:

  • Do I need to measure shallow or retained heap size?
  • Do I make the calculations for 32 or 64bit architecture?
  • Am I running on x86, SPARC, POWER or on something even beyond imagination?
  • Do I use compressed or uncompressed ordinary object pointers?
  • [enter something else you are afraid or do not completely understand here]

Bearing all those aspects in mind when trying to estimate the size of your data structures  is simply unreasonable when trying to meet yet another deadline. So we went ahead and packaged the code published by Java Champion Heinz Kabutz as a java agent and provided an easy way to add it to your application.

Adding the agent gives you an easy way to trace how much memory your data structures on your actual environment take. And does it without the complexity introduced by the alternatives. In the following four easy steps you are up&running and finally understanding how much memory do your precious caches actually consume:

Step 1: Download the agent. Don’t worry, its just few kilobytes.

Step 2: Unzip the downloaded agent. You see it is packaged along with it’s source code and a sample on how to use it. Feel free to play around with the code.

nikita-mb:sizeof nikita$ ls -l
total 16
-rw-r--r-- 1 nikita  staff  1696 Aug 28 22:12 build.xml
-rw-r--r--  1 nikita  staff  3938 Aug 28 22:33 sizeofagent.jar
drwxr-xr-x 5 nikita  staff    170 Aug 28 10:44 src

Step 3: Experiment with the bundled testcase. The bundled testcase measures the same data structure we described in our blog post about shallow heap size measurement. For those who do not bother clicking back and forth, here is the code again:

class X {
   int a;
   byte b;
   java.lang.Integer c = new java.lang.Integer();
class Y extends X {
   java.util.List d;
   java.util.Date e;

The testcase is shipped with Ant tests to compile and run the samples. Run ant test or ant test-32 if you are on a 32-bit architecture. You should see the following output when running all the tests with ant test:

nikita-mb:sizeof nikita$ ant test

Buildfile: /Users/nikita/workspace/sizeof/build.xml




     [java] java.lang.Object: shallow size=8 bytes, retained=8 bytes
     [java] eu.plumbr.sizeof.test.X: shallow size=24 bytes, retained=40 bytes
     [java] eu.plumbr.sizeof.test.Y: shallow size=32 bytes, retained=48 bytes


     [java] java.lang.Object: shallow size=16 bytes, retained=16 bytes
     [java] eu.plumbr.sizeof.test.X: shallow size=24 bytes, retained=40 bytes
     [java] eu.plumbr.sizeof.test.Y: shallow size=32 bytes, retained=48 bytes


     [java] java.lang.Object: shallow size=16 bytes, retained=16 bytes
     [java] eu.plumbr.sizeof.test.X: shallow size=32 bytes, retained=56 bytes
     [java] eu.plumbr.sizeof.test.Y: shallow size=48 bytes, retained=72 bytes


Total time: 2 seconds

From the test above you can see for example that on 32bit architecture, the shallow heap of Y consumes 32 bytes and retained heap 48 bytes. On 64bit architecture with -XX:-UseCompressedOops the shallow size increases to 48 bytes and retained heap size to 72 bytes. If it bedazzles you how do we calculate those numbers, then check out what is and how to calculate shallow and retained heap sizes from our previous posts in the series.

Step 4: Attach the agent to your very own Java application. To do this, add -javaagent:path-to/sizeofagent.jar to your JVM startup scripts. Now you can measure shallow heap consumption by invoking MemoryCounterAgent.sizeOf(yourObject) or measure retained heap consumption by invoking MemoryCounterAgent.deepSizeOf(yourObject) directly in your code. See the bundled ant scripts and eu.plumbr.sizeof.test.SizeOfSample class also in case you get confused while doing it.

Did you know that 20% of Java applications have memory leaks? Don’t kill your application – instead find and fix leaks with Plumbr in minutes.

Of course you have got numerous alternatives, especially in forms of memory profilers and APM solutions. But this small agent will do its task quickly and requires next to no set-up nor learning. Well, at minimum we had fun playing with it. Instead of crunching through our product backlog.

And – do not forget to send your congratulations for this code to Heinz Kabutz, who published it originally in its Java Specialists’ Newsletter in March 2007.