// ---------------------------------------------------------------------------- /** * A simple class to experiment with your JVM's garbage collector * and memory sizes for various data types. * * @author <a href="mailto:vlad@trilogy.com">Vladimir Roubtsov</a> */ public class Sizeof { public static void main (String [] args) throws Exception { // "warm up" all classes/methods that we are going to use: runGC (); usedMemory (); // array to keep strong references to allocated objects: final int count = 10000; // 10000 or so is enough for small ojects Object [] objects = new Object [count]; long heap1 = 0; // allocate count+1 objects, discard the first one: for (int i = -1; i < count; ++ i) { Object object; // INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object': object = new Object (); // 8 bytes //object = new Integer (i); // 16 bytes //object = new Long (i); // same size as Integer? //object = createString (10); // 56 bytes? fine... //object = createString (9)+' '; // 72 bytes? the article explains why //object = new char [10]; // 32 bytes //object = new byte [32][1]; // 656 bytes?! if (i >= 0) objects [i] = object; else { object = null; // discard the "warmup" object runGC (); heap1 = usedMemory (); // take a "before" heap snapshot } } runGC (); long heap2 = usedMemory (); // take an "after" heap snapshot: final int size = Math.round (((float)(heap2 - heap1))/count); System.out.println ("'before' heap: " + heap1 + ", 'after' heap: " + heap2); System.out.println ("heap delta: " + (heap2 - heap1) + ", {" + objects [0].getClass () + "} size = " + size + " bytes"); } // a helper method for creating Strings of desired length // and avoiding getting tricked by String interning: public static String createString (final int length) { final char [] result = new char [length]; for (int i = 0; i < length; ++ i) result [i] = (char) i; return new String (result); } // this is our way of requesting garbage collection to be run: // [how aggressive it is depends on the JVM to a large degree, but // it is almost always better than a single Runtime.gc() call] private static void runGC () throws Exception { // for whatever reason it helps to call Runtime.gc() // using several method calls: for (int r = 0; r < 4; ++ r) _runGC (); } private static void _runGC () throws Exception { long usedMem1 = usedMemory (), usedMem2 = Long.MAX_VALUE; for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++ i) { s_runtime.runFinalization (); s_runtime.gc (); Thread.currentThread ().yield (); usedMem2 = usedMem1; usedMem1 = usedMemory (); } } private static long usedMemory () { return s_runtime.totalMemory () - s_runtime.freeMemory (); } private static final Runtime s_runtime = Runtime.getRuntime (); } // end of class // ----------------------------------------------------------------------------