Calculate size of Object in Java [duplicate]
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())); }}
Look into https://github.com/DimitrisAndreou/memory-measurer.
Guava uses it internally, and ObjectGraphMeasurer
is especially straightforward to use out-of-the-box, without any special command-line arguments.
import objectexplorer.ObjectGraphMeasurer;public class Measurer { public static void main(String[] args) { Set<Integer> hashset = new HashSet<Integer>(); Random random = new Random(); int n = 10000; for (int i = 1; i <= n; i++) { hashset.add(random.nextInt()); } System.out.println(ObjectGraphMeasurer.measure(hashset)); }}
The java.lang.instrument.Instrumentation
class provides a nice way to get the size of a Java Object, but it requires you to define a premain
and run your program with a java agent. This is very boring when you do not need any agent and then you have to provide a dummy Jar agent to your application.
So I got an alternative solution using the Unsafe
class from the sun.misc
. So, considering the objects heap alignment according to the processor architecture and calculating the maximum field offset, you can measure the size of a Java Object. In the example below I use an auxiliary class UtilUnsafe
to get a reference to the sun.misc.Unsafe
object.
private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model"));private static final int BYTE = 8;private static final int WORD = NR_BITS/BYTE;private static final int MIN_SIZE = 16; public static int sizeOf(Class src){ // // Get the instance fields of src class // List<Field> instanceFields = new LinkedList<Field>(); do{ if(src == Object.class) return MIN_SIZE; for (Field f : src.getDeclaredFields()) { if((f.getModifiers() & Modifier.STATIC) == 0){ instanceFields.add(f); } } src = src.getSuperclass(); }while(instanceFields.isEmpty()); // // Get the field with the maximum offset // long maxOffset = 0; for (Field f : instanceFields) { long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f); if(offset > maxOffset) maxOffset = offset; } return (((int)maxOffset/WORD) + 1)*WORD; }class UtilUnsafe { public static final sun.misc.Unsafe UNSAFE; static { Object theUnsafe = null; Exception exception = null; try { Class<?> uc = Class.forName("sun.misc.Unsafe"); Field f = uc.getDeclaredField("theUnsafe"); f.setAccessible(true); theUnsafe = f.get(uc); } catch (Exception e) { exception = e; } UNSAFE = (sun.misc.Unsafe) theUnsafe; if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception); } private UtilUnsafe() { }}