获得Java对象内存占用大小

获得Java对象内存占用大小

懒惰,直接上代码,用法见JAVA DOC.
  1  package com.alibaba.stonelab.javalab.jvm.sizeof;
  2 
  3  import java.lang.instrument.Instrumentation;
  4  import java.lang.reflect.Array;
  5  import java.lang.reflect.Field;
  6  import java.lang.reflect.Modifier;
  7  import java.util.IdentityHashMap;
  8  import java.util.Map;
  9  import java.util.Stack;
 10 
 11  /**
 12   * <pre>
 13   * 1. MANIFEST.MF
 14   *      Premain-Class: xxx.yyy.zzz.JavaSizeOf
 15   * 
 16   * 2. MAIN.JAVA
 17   *         System.out.println(JavaSizeOf.sizeof(new ConcurrentHashMap<Object, Object>()));
 18   *         System.out.println(JavaSizeOf.sizeof(new String("1234567")));
 19   *         System.out.println(JavaSizeOf.sizeof(new String("1234")));
 20   *         System.out.println(JavaSizeOf.sizeof(new Object()));
 21   *         System.out.println(JavaSizeOf.sizeof(new int[] { 1, 2, 3 }));
 22   *         System.out.println(JavaSizeOf.sizeof(new CopyOnWriteArrayList<Object>()));
 23   *         System.out.println(JavaSizeOf.sizeof(null));
 24   *         
 25   * 3. USAGE:
 26   *      java -javaagent:sizeof.jar xxx.yyy.zzz.Main
 27   * </pre>
 28   * 
 29   *  @author  <a href="mailto:[email protected]">Stone.J</a> 2013-6-8
 30    */
 31  public  class JavaSizeOf {
 32 
 33      private  static Instrumentation inst;
 34 
 35      public  static  void premain(String agentArgs, Instrumentation inst) {
 36         JavaSizeOf.inst = inst;
 37     }
 38 
 39      /**
 40       * get size of java object.
 41       * 
 42       *  @param  o
 43       *  @return
 44        */
 45      public  static  long sizeof(Object o) {
 46          assert inst !=  null;
 47         Map<Object, Object> visited =  new IdentityHashMap<Object, Object>();
 48         Stack<Object> visiting =  new Stack<Object>();
 49         visiting.add(o);
 50          long size = 0;
 51          while (!visiting.isEmpty()) {
 52             size += analysis(visiting, visited);
 53         }
 54          return size;
 55     }
 56 
 57      /**
 58       * analysis java object size recursively.
 59       * 
 60       *  @param  visiting
 61       *  @param  visited
 62       *  @return
 63        */
 64      protected  static  long analysis(Stack<Object> visiting, Map<Object, Object> visited) {
 65         Object o = visiting.pop();
 66          if (skip(o, visited)) {
 67              return 0;
 68         }
 69         visited.put(o,  null);
 70          //  array.
 71           if (o.getClass().isArray() && !o.getClass().getComponentType().isPrimitive()) {
 72              if (o.getClass().getName().length() != 2) {
 73                  for ( int i = 0; i < Array.getLength(o); i++) {
 74                     visiting.add(Array.get(o, i));
 75                 }
 76             }
 77         }
 78          //  object.
 79           else {
 80             Class<?> clazz = o.getClass();
 81              while (clazz !=  null) {
 82                 Field[] fields = clazz.getDeclaredFields();
 83                  for (Field field : fields) {
 84                      if (Modifier.isStatic(field.getModifiers())) {
 85                          continue;
 86                     }
 87                      if (field.getType().isPrimitive()) {
 88                          continue;
 89                     }
 90                     field.setAccessible( true);
 91                      try {
 92                         visiting.add(field.get(o));
 93                     }  catch (Exception e) {
 94                          assert  false;
 95                     }
 96                 }
 97                 clazz = clazz.getSuperclass();
 98             }
 99         }
100          return inst.getObjectSize(o);
101     }
102 
103      /**
104       * <pre>
105       * skip statistics.
106       * </pre>
107       * 
108       *  @param  o
109       *  @param  visited
110       *  @return
111        */
112      protected  static  boolean skip(Object o, Map<Object, Object> visited) {
113          if (o  instanceof String) {
114              if (o == ((String) o).intern()) {
115                  return  true;
116             }
117         }
118          return o ==  null || visited.containsKey(o);
119     }
120 
121 }
122 

你可能感兴趣的:(获得Java对象内存占用大小)