Search this site


 Home  Java performance graphs  Java 5: Concurrent performance  Atomic variables  Explicit locks  Queues  Semaphores

Classmexer agent

 Download Classmexer 0.03
 Classmexer API

Classmexer is a simple Java instrumentation agent that provides some convenience calls for measuring the memory usage of Java objects from within an application. It currently provides the following static calls from the MemoryUtil class, inside the com.javamex.classmexer package:

  public static long memoryUsageOf(Object obj)
  public static long deepMemoryUsageOf(Object obj)
  public static long deepMemoryUsageOf(Object obj,
                                       VisibilityFilter referenceFilter)
  public static long deepMemoryUsageOfAll(Collection<? extends Object> objs)
  public static long deepMemoryUsageOfAll(Collection<? extends Object> objs,
                                         VisibilityFilter referenceFilter)

For more information about on these methods, see the examples below, plus the Classmexer API documentation.

Classmexer as an instrumentation agent and relies on the Java Instrumentation framework.

 See also: How to calculate the memory usage of a Java object

Installing Classmexer in your project

To set up your project to use Classmexer:

  • for compiling: include classmexer.jar in your project, or make sure you include it in the classpath if you are compiling from the command line;
  • for running: add -javaagent:classmexer.jar to the java command used to start your application, making sure that a copy of the jar is in the working directory (the directory from which you start the application— not necessarily the same as the classpath).

In your source code, you will need to import the class com.javamex.classmexer.MemoryUtil.

How to use MemoryUtil calls

The simplest call provided by the MemoryUtil class returns the number of bytes occupied by an object, not included any objects it refers to:

import com.javamex.classmexer.MemoryUtil;
...
long noBytes = MemoryUtil.memoryUsageOf(someObject);

This method is essentially a wrapper around the JDK method Instrumentation.getObjectSize(). As such, it doesn't always give a very relevant result. Usually it is more interesting to query the "deep" memory usage of an object, which includes "subobjects" (objects referred to by a given object). For example, if we try to query the memory usage of a string using memoryUsageOf(), we won't actually be including the characters of the string, because they're stored in a char array (a separate object) referenced by the String object itself.

The deepMemoryUsageOf() calls are designed to get round this problem. They recursively include "subobjects" or objects referred to by the "main" object(s) passed in. So to get the total memory usage of a string, we can use:

String str = "Some string or other";
long noBytes = MemoryUtil.deepMemoryUsageOf(str);

By default, the deepMemoryUsageOf() method traverses non-public references (i.e. objects with a private, protected or package-private reference). For many objects such as strings, this is the appropriate type of reference to follow: in effect, we include just those objects that in some sense "belong" to the main object (although the criterion isn't perfect: an object could still have a private reference to some "global" object). We can change which references are traversed by passing in an optional VisibilityFilter:

import com.javamex.classmexer.MemoryUtil;
import com.javamex.classmexer.MemoryUtil.VisibilityFilter;
..
long noBytes = MemoryUtil.deepMemoryUsageOf(someObject, VisibilityFilter.ALL);

In this example, all references will be traversed in counting the object's memory usage. Other options currently supported are NONE and PRIVATE_ONLY.

Total memory usage of multiple objects

The deepMemoryUsageOfAll() methods take a collection of objects and add up the total memory usage of all objects in the supplied collection. If no VisibilityFilter is provided, the default is NON_PUBLIC as above. These methods ensure that no object is counted more than once, even if objects have multiple references. (The single-object calls also make this guarantee, because it is of course possible for the object graph beginning with a single object to eventually include multiple references to the same object.)

Downloading Classmexer

See the download links at the top of the page.


Written by Neil Coffey. Copyright © Javamex UK 2008. All rights reserved.