Usage of the java object ? ask from JVM

If you are a Java developers who come from a C/C++ background have probably at one time wished for a Java equivalent of sizeof(). Java lacks a true sizeof() equivalent utility , but you can ask memory usage of the object from JVM by the Instrumentation framework introduced in Java 5. It can be used to get an estimate of the size of a particular object via its getObjectSize(Object)

General practise to use Instrumentation framework for estimation is following steps.  

  • create a special agent class with a special premain method, generally compiling it against the rest of our code so that it can see the definitions of the classes whose memory usage we’re interested in measuring;
  • the JVM passes a special Instrumentation object to  premain method (in agent class), which can use to query the size of an object;
  • package the compiled agent class into a jar with a special manifest file;
  • run the program, passing in the agent jar to the VM command line arguments.

Above procedure in details.

1. Creating the instrumentation agent class

An instrumentation agent is a class with a special method, with a predefined signature, that the JVM will invoke before the rest of the application for you to set up any instrumentation code. Generally, instrumentation is the act of transforming classes for profiling purposes: for example, we could manipulate the definition of the String class to increment a counter every time a string is created, and thus measure e.g. how many strings per second our application creates. But an interesting additional feature provided by the instrumentation framework is the ability to measure the memory usage of an object.

Agent is simply a class with the following method defined:

public static void premain(String args, Instrumentation inst) {
  ...
}

The JVM will pass to premain method an implementation of the Instrumentation interface, defined in java.lang.instrument. In turn, this interface defines the method getObjectSize(). So for example, if we want to measure the memory usage of an instance of SomeClass, our agent code would look as follows:

import java.lang.instrument.*;
import com.somepackage.SomeClass;

public class MyAgent {
  public static void premain(String args, Instrumentation inst) {
    SomeClass obj = new SomeClass();
    long size = inst.getObjectSize(obj);
    System.out.println("Bytes used by object: " + size);
  }
}

Note that there’s no interface that agent needs to define: we just need to make sure that we get the method signature correct so that the JVM will find it.

2. Package the agent into a jar

Once we have compiled our agent class, we need to package it into a jar. This step is slightly fiddly, because we also need to create a manifest file. The latter is simple a text file containing a single line that specifies the agent class. For example, you can create a file called manifest.txt with the following line:

Premain-Class: somepackage.MyAgent

Then, to create the jar, we execute the following command (it’s usually worth creating a batch file or shell script with this line in case you need to re-build the agent jar several times):

jar -cmf manifest.txt agent.jar somepackage/MyAgent.class

3. Run the application with the agent

Now, we execute the application as usual, but use the javaagent command line argument to specify that we want to attach our instrumentation agent. For example, assuming the classpath is the current directory and that the application’s main method is in com.mypackage.Main:

java -javaagent:agent.jar -cp .somepackage.Main

Now, before our application is run, our agent’s premain method will be run. And in this case, the size of an instance of SomeClass will be created.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s