Search this site
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.
Installing Classmexer in your project
To set up your project to use Classmexer:
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.)
See the download links at the top of the page.
Written by Neil Coffey. Copyright © Javamex UK 2008. All rights reserved.