1 10 package org.mmbase.util; 11 12 import java.lang.reflect.Array ; 14 import java.lang.reflect.Field ; 15 import java.lang.reflect.Modifier ; 16 import java.util.*; 17 18 import org.mmbase.util.logging.Logger; 19 import org.mmbase.util.logging.Logging; 20 21 72 public class SizeOf { 73 private static final Logger log = Logging.getLoggerInstance(SizeOf.class); 74 75 public static final int SZ_REF = 4; 76 private static int size_prim(Class t) { 77 if (t == Boolean.TYPE) return 1; 78 else if (t == Byte.TYPE) return 1; 79 else if (t == Character.TYPE) return 2; 80 else if (t == Short.TYPE) return 2; 81 else if (t == Integer.TYPE) return 4; 82 else if (t == Long.TYPE) return 8; 83 else if (t == Float.TYPE) return 4; 84 else if (t == Double.TYPE) return 8; 85 else if (t == Void.TYPE) return 0; 86 else return SZ_REF; 87 } 88 89 public static int sizeof(boolean b) { return 1; } 90 public static int sizeof(byte b) { return 1; } 91 public static int sizeof(char c) { return 2; } 92 public static int sizeof(short s) { return 2; } 93 public static int sizeof(int i) { return 4; } 94 public static int sizeof(long l) { return 8; } 95 public static int sizeof(float f) { return 4; } 96 public static int sizeof(double d) { return 8; } 97 98 private Set countedObjects = new HashSet(); 100 101 public static int getByteSize(Object obj) { 102 return new SizeOf().sizeof(obj); 103 } 104 105 109 public void clear() { 110 countedObjects.clear(); 111 } 112 116 public int sizeof(Object obj) { 117 if (obj == null) { 118 return 0; 119 } 120 121 if (!countedObjects.add(obj)) { 122 return 0; 123 } 124 125 Class c = obj.getClass(); 126 127 if (c.isArray()) { 128 log.debug("an array"); 129 return size_arr(obj, c); 130 } else { 131 if (log.isDebugEnabled()) { 132 log.debug("an object " + obj + " " + c); 133 } 134 try { 135 if (SizeMeasurable.class.isAssignableFrom(c)) return sizeof((SizeMeasurable) obj); 136 if (javax.servlet.http.HttpSession .class.isAssignableFrom(c)) return sizeof((javax.servlet.http.HttpSession ) obj); 137 if (org.w3c.dom.Node .class.isAssignableFrom(c)) return sizeof((org.w3c.dom.Node ) obj); 138 if (Map.class.isAssignableFrom(c)) return sizeof((Map) obj); 139 if (Collection.class.isAssignableFrom(c)) return sizeof((Collection) obj); 140 if (String .class.isAssignableFrom(c)) return sizeof((String ) obj); 141 if (Integer .class.isAssignableFrom(c)) return 16; 144 if (Long .class.isAssignableFrom(c)) return 16; 145 if (Float .class.isAssignableFrom(c)) return 16; 146 if (Double .class.isAssignableFrom(c)) return 16; 147 } catch (Throwable e) { 149 log.warn("Error during determination of size of " + obj + " :" + e.getMessage(), e); 150 } 151 return size_inst(obj, c); 152 } 153 } 154 155 private int sizeof(Map m) { 156 int len = 157 size_inst(m, m.getClass()) + 158 m.size() * 30; Iterator i = m.entrySet().iterator(); 160 while (i.hasNext()) { 161 Map.Entry entry = (Map.Entry) i.next(); 162 len += sizeof(entry.getKey()); 163 len += sizeof(entry.getValue()); 164 } 165 return len; 166 } 167 168 private int sizeof(Collection m) { 169 log.debug("sizeof List" ); 170 int len = size_inst(m, m.getClass()); 171 Iterator i = m.iterator(); 172 while (i.hasNext()) { 173 len += sizeof(i.next()); 174 } 175 return len; 176 } 177 178 private int sizeof(javax.servlet.http.HttpSession session) { 179 log.debug("sizeof HttpSession"); 180 int len = size_inst(session, session.getClass()); 181 Enumeration e = session.getAttributeNames(); 182 while (e.hasMoreElements()) { 183 String attribute = (String ) e.nextElement(); 184 len += sizeof(attribute); 185 len += sizeof(session.getAttribute(attribute)); 186 } 187 return len; 188 } 189 190 private int sizeof(org.w3c.dom.Node node) { 191 log.debug("sizeof Node"); 192 return sizeof(org.mmbase.util.xml.XMLWriter.write(node, false)); 194 } 195 196 private int sizeof(String m) { 197 return 44 + m.length() * 2; } 200 201 202 private int sizeof(SizeMeasurable m) { 203 if (log.isDebugEnabled()) { 204 log.debug("sizeof SizeMeasureable " + m); 205 } 206 return m.getByteSize(this); 207 } 208 209 210 private int size_inst(Object obj, Class c) { 211 Field flds[] = c.getDeclaredFields(); 212 int sz = 8; 214 for (int i = 0; i < flds.length; i++) { 215 Field f = flds[i]; 216 if (!c.isInterface() && (f.getModifiers() & Modifier.STATIC) != 0) { 217 continue; 218 } 219 sz += size_prim(f.getType()); 220 if (f.isAccessible()) { 222 try { 223 sz += sizeof(f.get(obj)); } catch (java.lang.IllegalAccessException e) { 225 log.trace(e); 227 } 228 } 229 } 230 231 if (c.getSuperclass() != null) { 232 sz += size_inst(obj, c.getSuperclass()) - 8; } 234 235 Class cv[] = c.getInterfaces(); 236 for (int i = 0; i < cv.length; i++) { 237 sz += size_inst(obj, cv[i]) - 8; } 239 240 return sz; 241 } 242 243 private int size_arr(Object obj, Class c) { 244 Class ct = c.getComponentType(); 245 int len = Array.getLength(obj); 246 247 if (ct.isPrimitive()) { 248 return len * size_prim(ct); 249 } else { 250 int sz = 0; 251 for (int i = 0; i < len; i++) { 252 Object obj2 = Array.get(obj, i); 253 sz += sizeof(obj2); 254 } 255 return sz; 256 } 257 } 258 259 public static void main(String argv[]) throws InterruptedException { 260 final Runtime rt = Runtime.getRuntime(); 261 final int SIZE = Math.round((float) Math.pow(10, 4)); 263 List list = new ArrayList(); 265 268 rt.runFinalization(); 269 rt.gc(); 270 Thread.sleep(1000); 271 long usedBefore = rt.totalMemory() - rt.freeMemory(); 272 for (int i = SIZE; i < 2 * SIZE; i++) { 274 list.add(new Integer (i)); 280 } 282 rt.runFinalization(); 283 rt.gc(); 284 Thread.sleep(1000); 285 long usedAfter = rt.totalMemory() - rt.freeMemory(); 286 System.out.println("" + SIZE +" of Integer costs " + (usedAfter - usedBefore) + " bytes"); 287 System.out.println("Sizeof reports: " + SizeOf.getByteSize(list) + " bytes"); 288 290 291 } 292 } 293 294
| Popular Tags
|