13

I want to estimate the size taken up by an object. To get the object's size I can just use

To do so I might use Instrumentation.getObjectSize(myObject), but this will give me a "shallow" size. I want to get the size of the Object, including the sizes of the objects it references.

My thought is that I need to get the size of the object, then go through all the object's fields that are not static or primitives and get the size for the objects that they point to and do this recursively.

Of course, I don't want to count an object size a few times, or get stuck in a loop, So I'll have to remember the objects which size we already counted.

Is there a faster, or a more standard, way to do this?

My code looks like this:

public static long getObjectSize(Object obj)
{
    return getObjectSize(obj, new HashSet<Object>());
}

private static long getObjectSize(Object obj, Set<Object> encountered)
{
    if (encountered.contains(obj))
    {
        // if this object was already counted - don't count it again
        return 0;
    }
    else
    {
        // remember to not count this object's size again
        encountered.add(obj);
    }
    java.lang.reflect.Field fields[] = obj.getClass().getFields();
    long size = Instrumentation.getObjectSize(obj);
    // itereate through all fields               
    for (Field field : fields)
    {
        Class fieldType = field.getType();
        // only if the field isn't a primitive
         if (fieldType != Boolean.class &&
             fieldType != Integer.class &&
             fieldType != Long.class &&
             fieldType != Float.class &&
             fieldType != Character.class &&
             fieldType != Short.class &&
             fieldType != Double.class)
         {
             // get the field's value
             try
             {
                 Object fieldValue = field.get(obj);
                 size += getObjectSize(obj, encountered);
             } 
             catch (IllegalAccessException e) {}
         }
    }
    return size;
}
Gilad
  • 833
  • 1
  • 8
  • 13
  • https://code.google.com/p/memory-measurer/ https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/objectsize/ObjectSizeCalculator.java – Louis Wasserman Jun 02 '13 at 20:29

1 Answers1

9

Try to serialize the object then get the size of the byte stream generated by serialization. that if you want to know the size of the object when persisted.

 public static byte[] serialize(Object obj) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(obj);
    return baos.toByteArray();
}
Mohammed Falha
  • 967
  • 8
  • 22
  • 1
    Is this a recommended practice? Are there alternatives? – David J. Feb 12 '14 at 17:20
  • I think this is the most accurate method, since serialization is a **byte per byte** representation of an object structure, and in the worst case it'll tell you a size a little bit bigger than the real one, but not smaller, which may cause size limit issues (it's better to have some space left than to exceed it). You might as well add the "shallow" object size (the one you get with the instrumentation class) to know the total size of an object once loaded into RAM, this of course doubles the size for every primitive object because they themselves are the reference to their own value. – arielnmz May 25 '14 at 08:46