stone2083

          獲得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:li.jinl@alibaba-inc.com">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 

          posted on 2013-06-08 17:32 stone2083 閱讀(7857) 評論(1)  編輯  收藏 所屬分類: java

          Feedback

          # re: 獲得Java對象內存占用大小 2013-06-08 19:16 開發吧

          代碼很實用,謝謝!  回復  更多評論   

          主站蜘蛛池模板: 漳浦县| 乌兰浩特市| 扶风县| 宁南县| 兴化市| 瑞安市| 连城县| 灌云县| 白山市| 沙雅县| 龙里县| 仙游县| 静安区| 台江县| 武陟县| 二手房| 腾冲县| 收藏| 乐安县| 迁西县| 方城县| 白银市| 集安市| 德州市| 巴南区| 贡觉县| 芒康县| 阿拉尔市| 临安市| 营口市| 海宁市| 泰顺县| 安福县| 高淳县| 五台县| 宾川县| 南漳县| 朔州市| 黄大仙区| 沅江市| 栖霞市|