001: package clime.messadmin.providers.sizeof;
002:
003: import java.lang.reflect.Array;
004: import java.lang.reflect.Field;
005: import java.lang.reflect.Modifier;
006:
007: /* http://www.glenmccl.com/tip_038.htm modified 1999-10 */
008: /**
009: * Sizeof For Java(tm)
010:
011: Java(tm) has no sizeof() operator like C/C++.With uniform sizes for primitive data types,
012: and a different style of memory allocation, the need for sizeof() really isn't there.
013: And it's hard to define what sizeof() would mean anyway, given that an object may not
014: contain other objects, but only references to them.
015:
016: But it's interesting to experiment with the 1.1 reflection feature and see whether a
017: method can be devised that will return useful information about object sizes.
018:
019: The Sizeof class below tries to do this, for a passed-in data structure. It walks the
020: structure and tallies up the total size in bytes. It ignores alignment and packing issues
021: and hidden fields in structures, and assumes a boolean is of size 1 and a reference of
022: size 4 (reference sizes may vary; for example SZ_REF might be 8 on a machine with 64-bit pointers).
023:
024: It does not count static data members of class instances, but does include members
025: inherited/implemented from superclasses and interfaces. It does not follow references in
026: object instances or in arrays, except for the case of a multi-dimensional array, where the
027: reference is to another array.
028: */
029: public class NaiveSizeOf {
030:
031: private NaiveSizeOf() {
032: super ();
033: }
034:
035: private static final int SZ_REF = 4;
036:
037: public static int sizeof(boolean b) {
038: return 1;
039: }
040:
041: public static int sizeof(byte b) {
042: return 1;
043: }
044:
045: public static int sizeof(char c) {
046: return 2;
047: }
048:
049: public static int sizeof(short s) {
050: return 2;
051: }
052:
053: public static int sizeof(int i) {
054: return 4;
055: }
056:
057: public static int sizeof(long l) {
058: return 8;
059: }
060:
061: public static int sizeof(float f) {
062: return 4;
063: }
064:
065: public static int sizeof(double d) {
066: return 8;
067: }
068:
069: private static int size_inst(final Class c) {
070: Field flds[] = c.getDeclaredFields();
071: int sz = 0;
072:
073: for (int i = 0; i < flds.length; ++i) {
074: Field f = flds[i];
075: if (!c.isInterface()
076: && (f.getModifiers() & Modifier.STATIC) != 0)
077: continue;
078: sz += size_prim(f.getType());
079: }
080:
081: if (c.getSuperclass() != null)
082: sz += size_inst(c.getSuperclass());
083:
084: Class cv[] = c.getInterfaces();
085: for (int i = 0; i < cv.length; ++i)
086: sz += size_inst(cv[i]);
087:
088: return sz;
089: }
090:
091: private static int size_prim(final Class t) {
092: if (t == Boolean.TYPE)
093: return 1;
094: else if (t == Byte.TYPE)
095: return 1;
096: else if (t == Character.TYPE)
097: return 2;
098: else if (t == Short.TYPE)
099: return 2;
100: else if (t == Integer.TYPE)
101: return 4;
102: else if (t == Long.TYPE)
103: return 8;
104: else if (t == Float.TYPE)
105: return 4;
106: else if (t == Double.TYPE)
107: return 8;
108: else if (t == Void.TYPE)
109: return 0;
110: else
111: return SZ_REF;
112: }
113:
114: private static int size_arr(final Object obj, final Class c) {
115: Class ct = c.getComponentType();
116: int len = Array.getLength(obj);
117:
118: if (ct.isPrimitive()) {
119: return len * size_prim(ct);
120: } else {
121: int sz = 0;
122: for (int i = 0; i < len; ++i) {
123: sz += SZ_REF;
124: Object obj2 = Array.get(obj, i);
125: if (obj2 == null)
126: continue;
127: Class c2 = obj2.getClass();
128: if (!c2.isArray())
129: continue;
130: sz += size_arr(obj2, c2);
131: }
132: return sz;
133: }
134: }
135:
136: public static int sizeof(final Object obj) {
137: if (null == obj)
138: return 0;
139:
140: Class c = obj.getClass();
141:
142: if (c.isArray())
143: return size_arr(obj, c);
144: else
145: return size_inst(c);
146: }
147:
148: }
|