Skip to main content

Measuring the size of your objects reloaded

Posted by mister__m on January 12, 2007 at 10:56 AM PST

The requirements for defining an agent using the java.lang.instrument package have changed since I've done my first experiments with it for calculating the size of arbitrary objects three years ago. Many folks have asked me how to make that sample work with the final API and while I have told them the directions, they have not always succeeded in their task.

So, here are the steps to build a working agent capable of computing the size of your objects. First, let's create the agent class:

package br.com.michaelnascimento.javaagentsample;

import java.lang.instrument.Instrumentation;
import java.util.Calendar;

public class ObjectSizeCalculator {
   private static Instrumentation instrumentation;

   public static void premain(String agentArgs, Instrumentation inst) {
      instrumentation = inst;
   }

   private static long sizeOf(Object o) {
      return instrumentation.getObjectSize(o);
   }

   public static void main(String[] args) {
      System.out.println("Size of Object: " + sizeOf(new Object()));
      System.out.println("Size of direct subclass: " + sizeOf(
            new ObjectSizeCalculator()));
      System.out.println("Size of String "size": " + sizeOf("size"));
      System.out.println("Size of Calendar: " + sizeOf(Calendar.getInstance()));  
   }
}

One requirement for an agent that is started with the JVM is to have a premain method with one of two signatures. The other possible one would just take a String.

Now, the main change made to agent definition is that an agent must be packaged on a jar and must be identified by a manifest attribute, Premain-Class. It shouldn't be too hard to do this with your favourite IDE. With NetBeans, you just need to create a Java Application and make the following changes:

  1. Create a MANIFEST.MF file in the root directory of your project with the following content:
    Premain-Class: br.com.michaelnascimento.javaagentsample.ObjectSizeCalculator
  2. Configure your project to use this file by adding the following property to nbproject/project.properties:
    manifest.file=MANIFEST.MF

Once you build your project, your agent will be properly packaged and ready to be used. To load it, though, you need to use the -javaagent: command-line option to define the jar that contains your agent. If you are using NetBeans, you just need to edit nbproject/project.properties again in order to replace the definition of run.jvmargs by the following one:

run.jvmargs=-javaagent:${dist.jar}

That is it. Running the sample in my machine produces:

Size of Object: 8
Size of direct subclass: 8
Size of String "size": 24
Size of Calendar: 112

As a final note, agents are actually intended to allow your code to redefine classes by replace sections of their bytecode as desired. This technique is used by AspectWerkz and AspectJ, for instance, and can also be used for special tasks, such as enabling/disabling specific monitoring, for instance. The object size calculation capability is there, but it is not its main purpose.

PS: genesis has been the most active project in December. 3.0 RC1 should be out in a few days.

Related Topics >>