2

Possible Duplicate:
In Java, what is the best way to determine the size of an object?

Suppose you have a data structure which allows you to add data to it, say a list:

List<KeyValuePair>

As client of the system actually adds content ... at some point, JVM will run out of memory, it is only a question of when this happens. It would be nice to periodically save the object that contains this list to disk and gc the rest.

Using Java, is it possible to estimate how much memory an object is taking now?

Community
  • 1
  • 1
James Raitsev
  • 92,517
  • 154
  • 335
  • 470

3 Answers3

3

The getObjectSize() method might be what you're looking for.
Quote from the Interface Instrumentation documentation:

getObjectSize(Object objectToSize)
Returns an implementation-specific approximation of the amount of storage consumed by the specified object.

Anne
  • 26,765
  • 9
  • 65
  • 71
3

You are looking for java.lang.instrument.Instrumentation.getObjectSize(Object object)

Documentation:

Returns an implementation-specific approximation of the amount of storage consumed by the specified object. The result may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations. The estimate may change during a single invocation of the JVM.

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

But in order to be able to use it:

The only way to access an instance of the Instrumentation interface is for the JVM to be launched in a way that indicates the agent class - see the package specification. The Instrumentation instance is passed to the premain method of the agent class. Once an agent acquires the Instrumentation instance, the agent may call methods on the instance at any time.

Good implementation sample: http://www.javalobby.org/java/forums/t19309.html

Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
1

You can do it by making a lot of same objects and measuring the memory taken. I have used this technique several times now with stable, repeatable results. In an outline,

public static void main(String[] args) {
  final Object[] a = new Object[10000];
  final long startMem = memTaken();
  for (int i = 0; i < a.length; i++) a[i] = new Object();
  System.out.println((memTaken() - startMem) / a.length);
  a.hashCode();
}
static long memTaken() {
  final Runtime rt = getRuntime();
  try {
    rt.gc(); Thread.sleep(50);
    rt.gc(); Thread.sleep(50);
  } catch (InterruptedException e) {}
  final long memTaken = rt.totalMemory() - rt.freeMemory();
  System.out.println("Mem taken " + memTaken);
  return memTaken;
}

This reliably produces the number 24 on my machine. The advantage of this approach is that it automatically takes into account the effective heap impact of your object, with everything factored in. You should, of course, check that it is reliable on your setup before trusting it.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436