Saturday, January 25, 2014

Java's sizeOf()

Java does have a C-like sizeOf() method. Sort of. It lives in the Instrumentation interface and is called getObjectSize. Note: it gives a shallow size but there are ways of getting the deep size of your object (see below).

You have to register your class as an agent which is a schlepp but not too hard. First, create a JAR which declares your class as its agent. In Maven, you can do this by adding the following your pom:

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <archive>
            <index>true</index>
            <manifest>
              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
            <manifestEntries>
              <Premain-Class>YOUR_CLASS_WITH_A_PREMAIN_METHOD</Premain-Class>
            </manifestEntries>
          </archive>
        </configuration>
      </plugin>
.
.

The class must have a static premain method that may look like this:

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain");
        instrumentation = inst;
    }
    
    static Instrumentation instrumentation;

You then run your JVM with:

-javaagent:YOUR_JAR_FILENAME

and your premain method will run before your main. Note, you can have multiple javaagents on your command line if you want more than one agent.

The size of objects is JVM-dependent. For instance, we've upgraded to 64-bit JVMs and started getting out of memory exceptions. This was not too surprising as our references our now 64 bit not 32. Running this code:


System.out.println("new Hashmap(1) " + instrumentation.getObjectSize(new HashMap(1)));

outputs on a 64-bit JVM

new Hashmap(1) 80 

and on a 32-bit JVM:

new Hashmap(1) 56 

You can get the deep size of objects by using this library which just traverses the map of objects and adds up the sizes. You need to add the JAR of the SizeOf library as an agent to use it.




No comments:

Post a Comment