How to use the Java Instrumentation API to determine object size?
The instrumentation tools

1. What is Java agent?

In Java 1.5 Instrumentation API was introduced (java.lang.instrument package) to enable byte-code modification (instrumentation) of classes and to get runtime insights. This is very helpful to tool developers. In this article, we’ll see how Instrumentation API can be leveraged to determine approximate object size at runtime.

Java agent is packaged as a plain Jar containing a set of classes having some specific methods. When an application is run with a Java agent, the agent performs the required instrumentations.

2. Starting Java agent

Java agent can be started either statically or dynamically in a running JVM. To start Java agent statically, add the javaagent option while launching the application:

java -javaagent:myagent.jar org.openapex.samples.misc.instrument.ObjectSize

To start a Java agent in a running JVM, do the following:

VirtualMachine vm = VirtualMachine.attach(jvmPid); // target JVM PID
vm.loadAgent(agentFile.getAbsolutePath());

3. Creating Java agent

If you plan to start the Java agent statically, then create a class with the following premain method. This method is called by the JVM to start the agent.



public class MyInstrumentationAgent {
    public static void premain(String agentArgs, Instrumentation inst){
        System.out.println("Set the instrumentation from premain");
        // Attach class transformers
    }
}

In case you plan to start the Java agent dynamically, then create a class with the following agentmain method. This method is called by the JVM to start the agent.

public class MyInstrumentationAgent {
    public static void agentmain(String agentArgs, Instrumentation inst){
        System.out.println("Set the instrumentation from agentmain");
        // Attach class transformers
    }
}

If you want to have the flexibility to start the agent both statically and dynamically, you may define both the methods in the same class.

Now, create a JAR in the usual way using jar command and ensure the following entries (Premain-class and Agent-class) are present in the manifest file.

Premain-Class: org.openapex.samples.misc.instrument.MyInstrumentationAgent
Agent-Class: org.openapex.samples.misc.instrument.MyInstrumentationAgent

Create the agent JAR:

jar -cvfm myagent.jar manifest.txt org/openapex/samples/misc/instrument/MyInstrumentationAgent.class

4. Determine Object size

In the previous sections, we have seen what is Java agent and how to create one for instrumentation. Let us see how we can create a Java agent and leverage Instrumentation.getObjectSize(obj) to determine object size. Define an agent class with both premain() and agentmain() methods. Keep the reference of Instrumentation object and later use it to get the object size.



package org.openapex.samples.misc.instrument;

import java.lang.instrument.Instrumentation;

public class MyInstrumentationAgent {
    private static Instrumentation instrumentation;

    public static void premain(String agentArgs, Instrumentation inst){
        instrumentation = inst;
        System.out.println("Set the instrumentation from premain");
    }
    public static void premain(String agentArgs){
        System.out.println("Unable to set instrumentation premain");
    }

    public static void agentmain(String agentArgs, Instrumentation inst){
        instrumentation = inst;
        System.out.println("Set the insttrumentation from agentmain");
    }
    public static void agentmain(String agentArgs){
        System.out.println("Unable to set instrumentation agentmain");
    }

    public static long getObjectSize (Object object){
        if (instrumentation != null){
            return instrumentation.getObjectSize(object);
        }
        System.out.println("Unable to determine object size, instrumentation is not available");
        return 0;
    }
}

Let us define the application class that will determine object size. In this example, we get the approximate object size of a File, String and Integer.

package org.openapex.samples.misc.instrument;

import java.io.File;
import java.lang.instrument.Instrumentation;

public class ObjectSize {
    public static void main(String[] args) {
        File f = new File("data/user.csv");
        String hello = "Hello World";
        Integer num = Integer.valueOf(100);
        System.out.println("Size of file object: " + MyInstrumentationAgent.getObjectSize(f));
        System.out.println("Size of file string: " + MyInstrumentationAgent.getObjectSize(hello));
        System.out.println("Size of file integer: " + MyInstrumentationAgent.getObjectSize(num));
    }
}

Start the application by adding javaagent option:

java -javaagent:myagent.jar org.openapex.samples.misc.instrument.ObjectSize

Here is the output from ObjectSize application:

Size of file object (bytes): 32
Size of string (bytes): 24
Size of integer (bytes): 16

5. Byte-code modification

If you want to modify byte-code from your Java agent, create one or more ClassFileTransformer and add these to the Instrumentation object from premain() or agentmain() methods.

The ClassFileTransormer looks like:

public class MyClassTransformer implements ClassFileTransformer{
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        // Here change the byte code as needed
        byte[] newbytes = new byte[100];
        return newbytes;
    }
}

Add the transformer to the Instrumentation object:

public static void premain(String agentArgs, Instrumentation inst){
    instrumentation = inst;
    System.out.println("Set the instrumentation from premain");
    instrumentation.addTransformer(new MyClassTransformer());
}

6. Conclusion

In this article, we have seen how to create a simple Java agent and use it in an application. The possible uses cases of instrumentation are limitless. The source code, manifest file, agent Jar files can be downloaded from GitHub

How to use the Java Instrumentation API to determine object size?
Be The First

Join our list to get instant access to new articles and weekly newsletter.

Tagged on:     
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x