I search and found there are different way of checking object memory created for Java.
1. One is done by checking Runtime memory available
https://stackoverflow.com/a/383597
2. The other one is using the ByteArrayOutputStream to check
https://stackoverflow.com/a/38188384/3286489
So I have written a program using both approach and check if they are the same
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class LotsOfBooleans implements Serializable
{
    boolean a0;
}
class LotsOfInts implements Serializable
{
    int a0;
}
public class Test
{
    private static final int SIZE = 1000000;
    public static void main(String[] args) throws Exception
    {        
        LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];
        System.gc();
        long startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            first[i] = new LotsOfBooleans();
        }
        System.gc();
        long endMem = getMemory();
        System.out.println ("Size for LotsOfBooleans (by checking Runtime) : " + (endMem-startMem));
        System.gc();
        startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            second[i] = new LotsOfInts();
        }
        System.gc();
        endMem = getMemory();
        System.out.println ("Size for LotsOfInts (by checking Runtime memory) : " + (endMem-startMem));
        System.out.println ("Size for LotsOfBooleans (using ByteArrayOutputStream) : " + getBytes(first).length);
        System.out.println ("Size for LotsOfInts (using ByteArrayOutputStream) : " + getBytes(second).length);
        // Make sure nothing gets collected
        long total = 0;
        for (int i=0; i < SIZE; i++)
        {
            total += (first[i].a0 ? 1 : 0) + second[i].a0;
        }
        System.out.println(total);
    }
    private static long getMemory()
    {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
    private static byte[] getBytes(Object o) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutput out = null;
        try {
            out = new ObjectOutputStream(bos);
            out.writeObject(o);
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException ex) {
                // ignore close exception
            }
            try {
                bos.close();
            } catch (IOException ex) {
                // ignore close exception
            }
        }
        return null;
    }
}
I compile it using https://www.tutorialspoint.com/compile_java_online.php
The result as below
$javac Test.java
$java -Xmx128M -Xms16M Test
Size for LotsOfBooleans (by checking Runtime) : 15914240
Size for LotsOfInts (by checking Runtime memory) : 15999984
Size for LotsOfBooleans (using ByteArrayOutputStream) : 7000072
Size for LotsOfInts (using ByteArrayOutputStream) : 10000064
0
From the result, clearly shows they are different. I have the feeling that ByteArrayOutputStream is more accurate. But the checking Runtime approach is by @jon-skeet, which is from a renown StackoverFlow contributor.
So which one should I refer to?
Or both of them are correct, but referring to a different size of object (mind explaining how they are different if both are correct?
If both approach is not right, do suggest what is a good way to know the size of my object in Java?
