Method 1: Serialize the object and measure the size of the byte stream.
Problem: But that would not work because objects are not the same size when they are resident in the JVM and when they are serialized. The way the objects are encoded changes the actual size of the object.
Example: Strings. Every character is two bytes in memory and lesser than that when the object is encoded using the UTF-8 encoding format before serialization.
Method 2: Create a large number of identical class instances and carefully measure the resulting increase in the JVM used heap size.
Method 3: An object instance can be (approximately) sized by totaling all of its non-static data fields (remember to include fields defined in the superclass). Class super interfaces have no impact on the object size. the full object size can be obtained as a closure over the entire object graph rooted at the starting object.
// java.lang.Object shell size in bytes:
public static final int OBJECT_SHELL_SIZE = 8;
public static final int OBJREF_SIZE = 4;
public static final int LONG_FIELD_SIZE = 8;
public static final int INT_FIELD_SIZE = 4;
public static final int SHORT_FIELD_SIZE = 2;
public static final int CHAR_FIELD_SIZE = 2;
public static final int BYTE_FIELD_SIZE = 1;
public static final int BOOLEAN_FIELD_SIZE = 1;
public static final int DOUBLE_FIELD_SIZE = 8;
public static final int FLOAT_FIELD_SIZE = 4;