001: package junit.extensions.abbot;
002:
003: import java.util.ArrayList;
004:
005: public class SizeOf {
006:
007: /** For use with constructors which require arguments. */
008: public static interface ObjectCreator {
009: Object create();
010: }
011:
012: private static class ClassCreator implements ObjectCreator {
013: private Class cls;
014:
015: public ClassCreator(Class cls) {
016: this .cls = cls;
017: }
018:
019: public Object create() {
020: try {
021: return cls.newInstance();
022: } catch (IllegalAccessException e) {
023: String msg = "No-argument constructor is "
024: + "private for " + cls;
025: throw new IllegalArgumentException(msg);
026: } catch (InstantiationException e) {
027: String msg = "Can't create an instance of " + cls;
028: throw new IllegalArgumentException(msg);
029: } catch (Exception e) {
030: e.printStackTrace();
031: String msg = "Can't obtain size of " + cls;
032: throw new IllegalArgumentException(msg);
033: }
034: }
035: }
036:
037: private static final int GCCOUNT = 2;
038:
039: private static void gc() {
040: try {
041: System.gc();
042: Thread.sleep(100);
043: System.runFinalization();
044: Thread.sleep(100);
045: } catch (InterruptedException e) {
046: }
047: }
048:
049: private static void gc(int n) {
050: for (int i = 0; i < n; i++) {
051: gc();
052: }
053: }
054:
055: public static long getMemoryUse() {
056: gc(GCCOUNT);
057: long total = Runtime.getRuntime().totalMemory();
058: long free = Runtime.getRuntime().freeMemory();
059: return total - free;
060: }
061:
062: /** Return the approximate size in bytes of the object returned by the
063: given ObjectCreator.
064: */
065: public static long sizeof(ObjectCreator oc) {
066: final int SIZE = 1000;
067: ArrayList list = new ArrayList(SIZE);
068: long before = getMemoryUse();
069: for (int i = 0; i < SIZE; i++) {
070: list.add(oc.create());
071: }
072: long after = getMemoryUse();
073: return (after - before) / SIZE;
074: }
075:
076: /** Return the approximate size in bytes of an instance of the given
077: class. The class <em>must</em> provide a no-args constructor.
078: */
079: public static long sizeof(Class cls) {
080: return sizeof(new ClassCreator(cls));
081: }
082:
083: /** Display the approximate size (in bytes) of the class given in the
084: first argument.
085: */
086: public static void main(String[] args) {
087: try {
088: if (args.length != 1) {
089: System.err
090: .println("Use with a single class name argument");
091: System.exit(1);
092: }
093: Class cls = Class.forName(args[0]);
094: System.out.println("Class " + cls.getName() + " size is "
095: + sizeof(cls) + " bytes");
096: } catch (Throwable e) {
097: e.printStackTrace();
098: System.exit(1);
099: }
100: }
101: }
|