0

If i have an object and want to work out a rough estimate about the size of the object in comparison with the size of its components can I do this?

The Object has an int field and a float field. So the space usage of that object is the size of the reference to that object(8)bytes + the size of the two primitave values 16+16 which gives me 40bytes or 25% extra space needed.

DavyGravy
  • 311
  • 1
  • 4
  • 14
  • object will also have reference to it's base class. and size of reference will matter if it exist within object, (not within a function). – Azodious Feb 12 '13 at 10:57
  • The size of the reference is mostly 4 bytes due to OOP compression (google it). An empty `Object` occupies 16 (or was it 24?) bytes of pure overhead (monitor, type tag, various flags). And the total is once again word-aligned to an 8-byte boundary. – Marko Topolnik Feb 12 '13 at 10:59
  • The best way to find out is to measure by allocating a largish array of your objects and comparing memory usage before and after. You must also take care of GC-ing, and convince yourself that the results are deterministic for your JVM and setup. – Marko Topolnik Feb 12 '13 at 11:00

2 Answers2

4

One way to check the approximate size of an object is to create many instances of that object and check the memory before and after. To get more accurate figures, you can use a specific JVM arguments:

-verbose:gc -XX:-UseTLAB
  • verbose:gc to make sure no GC occurs in the middle of the measurement
  • -XX:-UseTLAB asks the JVM not to allocate memory in chunks (which it otherwise does for efficiency). Turning that option off gives more accurate and stable results.

You can then monitor the memory usage by calling Runtime.getRuntime().freeMemory(); before and after allocation.

Note that adding a field does not necessarily increase memory usage. For example, on hotspot 7 64 bit, an object takes 16 bytes in memory, but adding an int field to that object does not change the size (i.e. a object that holds one int field is also 16 byte on that JVM). This is due to memory alignment constraints.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • 1
    +1 I've already seen the `Instrumentation` technique give results less accurate than this "crude" one. It didn't take into account OOP compression, for one. – Marko Topolnik Feb 12 '13 at 11:03
  • @MarkoTopolnik The main issue with this approach is that depending on the order in which you allocate your objects, the results can vary which I've never quite understood. But by testing several times in various orders you generally manage to get an accurate result. – assylias Feb 12 '13 at 11:07
  • 1
    I'd call that another **advantage** of this method---showing what the real issues are. An object is not a `struct` so who knows what's going on. – Marko Topolnik Feb 12 '13 at 11:16
0

You can use the java.lang.instrumentation package:

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

It has a method that can be used to get the implementation specific approximation of object size, as well as overhead associated with the object.

The answer that Sergey linked has a great example, which I'll repost here, but you should have already looked at from his comment:

import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
private static Instrumentation instrumentation;

public static void premain(String args, Instrumentation inst) {
    instrumentation = inst;
}

public static long getObjectSize(Object o) {
    return instrumentation.getObjectSize(o);
}
}

Use getObjectSize:

public class C {
private int x;
private int y;

public static void main(String [] args) {
    System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
}

}

Vallabh Patade
  • 4,960
  • 6
  • 31
  • 40