In Java, How to Determine the Size of an Object

Calculate size of Object in Java

You can use the java.lang.instrumentation package.

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()));
}
}

Source

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

You can use the java.lang.instrument package.

Compile and put this class in a JAR:

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);
}
}

Add the following to your MANIFEST.MF:

Premain-Class: ObjectSizeFetcher

Use the getObjectSize() method:

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

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

Invoke with:

java -javaagent:ObjectSizeFetcherAgent.jar C

Is there a simple way to get the size of a java object?

There is an opensource java.SizeOf project that determines size of any of your Java object in memory.

What is the size of the object in java

The in-memory size of the object depends on the architecture, mainly on whether the VM is 32 or 64-bit. The actual VM implementation also matters.

For each object, you need space for its object header (typically 2*8 bytes on 64-bit VMs), its fields (extra space for alignment depending on the VM implementation). The final space is then rounded up to the nearest multiple of the word size.

sizeof Java object

The question is not meaningful, at least not without further context.

The notion of "size" in Java is only reasonably well defined for primitives: A byte is 8 bit (unsurprisingly) an int is 32 bit, a long 64bit, etc. (see e.g. http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html for a full list).

For object instances, it's more complicated, because:

  • Object instances can (and usually will) contain references to other instances internally, so you must decide whether to count these dependent instances, and how. What if several instances share a dependency?
  • Sometimes, object instances may be reused (e.g. interning of java.lang.String, see http://en.wikipedia.org/wiki/String_interning ). So if you use x objects of size y, the total size may be smaller than x*y
  • The JVM has a lot of leeway about how to implement objects and instances internally.
    It may use different techniques for different instances (e.g. sharing internal data structures), so there may not even be a meaningful "size" to assign to a single object.

Maybe you could explain why you are interested in object sizes.

There are some rules of thumb for estimating the heap memory used by instances (e.g. in the Sun JVM, a java.lang.Object instance uses 8 byte), but these will depend on the JVM you use.

Generally, if you want to know about your heap usage, use a memory / heap profiler.

Edit:

Well, there is (as of JDK 6) a way to get an approximation of the amount of memory used by an object: http://download.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

It's still only an approximation...

Where to find the evidence of how to calculate the size of a java object

how to calculate out the actual size. But how do they know that?

from experience.

I did not find any evidence from the official oracle documents.

Its up to the JVM. For OpenJDK based JVMs, 32-bit JVM has a different header size to 64-bit JVM as the header contains a reference. Other JVMs could be different again.

Or the data was just come from some guesses based on some experiments?

Essentially, yes.

can anybody explain to me what is the 'approximately' means?

When you measure the size of an object it can means many different things

  • How big is the object? (Shallow depth)
  • How much memory does it use? (Object allocation is 8-byte aligned i.e. always a multiple of 8)
  • How much space does the object and all the objects referenced use? (Deep depth)
  • How much space might be freed if it were discarded? (how many objects are shared and does it appear in the middle of two fragments of freed memory)
  • Do you count the space used on the stack, or space used in off heap memory?

Given you can have many difference answers depending on what you need to know, it is useful to have one number which is approximately close to all of these which you use for calculations.


Where you get a problem using Runtime is that the TLAB allocated data in large blocks. These large blocks can be further allocated in a multi-thread way. The downside is you don't get accurate memory used information.

static long memTaken() {
final Runtime rt = Runtime.getRuntime();
return rt.totalMemory() - rt.freeMemory();
}

public static void main(String... args) {
long used1 = memTaken();
Float i = new Float(0);
long used2 = memTaken();
System.out.println("new Float(0) used "+(used2 - used1)+" bytes.");
}

run without options

new Float(0) used 0 bytes.

Turn off the TLAB and you see with -XX:-UseTLAB

new Float(0) used 336 bytes.

This is much higher than you might expect because the class itself had to be loaded. If you create one instance of a Float first by adding to the start

Float j = new Float(1);

you get

new Float(0) used 16 bytes


Related Topics



Leave a reply



Submit