Measuring the size of your objects reloaded
Posted by mister__m on January 12, 2007 at 10:56 AM | Comments (2)
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:
- Create a
MANIFEST.MF file in the root directory of your project with the following content:
Premain-Class: br.com.michaelnascimento.javaagentsample.ObjectSizeCalculator
- 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.
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Hello Michael,
See also my version http://www.jroller.org/page/maxim?entry=again_about_determining_size_of
It uses same approach and also allows determining full size of
object including member variable hierarchy.
Regards,
Maxim
Posted by: maxz1 on January 15, 2007 at 02:41 AM
-
Hi Michael
Small question - just in case you familiar with instrumentation related tags of MANIFEST.MF. If the Agent-Class is specified - do you know how JVM recognizes that new ClassFileTransformer just being added? - Instrumentation package docs says "may provide a mechanism to start agents sometime after the the VM has started.. The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path" Does it mean the SystemClassLoader triggers the event, so it scans jar and rans specified class? I tried it but it dooes not happen..
Sincerely, Jabb
Posted by: jabberw on November 29, 2007 at 02:24 AM
|