获得Java对象内存占用大小

标签: java 对象 内存 | 发表时间:2013-06-08 17:32 | 作者:stone2083
出处:http://www.blogjava.net/
懒惰,直接上代码,用法见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 


stone2083 2013-06-08 17:32 发表评论

相关 [java 对象 内存] 推荐:

JAVA内存使用--如何计算一个Java对象占用的字节数

- - Java - 编程语言 - ITeye博客
转自(http://blog.csdn.net/kp034/article/details/7077757). 通常,我们谈论的堆内存使用的前提是以“一般情况”为背景的. 1.某些情况下,JVM根本就没有把Object放入堆中. 例如:原则上讲,一个小的thread-local对象存在于栈中,而不是在堆中.

获得Java对象内存占用大小

- - BlogJava-首页技术区
懒惰,直接上代码,用法见JAVA DOC. stone2083 2013-06-08 17:32 发表评论.

一个Java对象到底占用多大内存? - zhanjindong

- - 博客园_首页
最近在读《深入理解Java虚拟机》,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存. 在网上搜到了一篇博客讲的非常好: http://yueyemaitian.iteye.com/blog/2033046,里面提供的这个类也非常实用:.

Java程序计算各种对象所占内存的大小的方法

- - Java - 编程语言 - ITeye博客
System.out.println("--- Memory Usage:"); /*打印一行字符串---Memory Usage*/. Runtime rt=Runtime.getRuntime( ); //获得系统的Runtime对象rt. System.out.println("Total Memory= " + rt.totalMemory( )+//打印总内存大小.

JAVA内存释放

- - Java - 编程语言 - ITeye博客
(问题一:什么叫垃圾回收机制. ) 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能. 当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用,以免造成内存泄露. (问题二:java的垃圾回收有什么特点. ) JAVA语言不允许程序员直接控制内存空间的使用.

Java 堆内存(Heap)

- - ITeye博客
        堆(Heap)又被称为:优先队列(Priority Queue),是计算机科学中一类特殊的数据结构的统称. 堆通常是一个可以被看做一棵树的数组对象. 在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.

java内存泄漏

- - 编程语言 - ITeye博客
不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址. Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的. GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.

Java的对象驻留

- - Java译站
Java会将源代码中的字符串常量存储到常量池中. 这不只是说它俩的值是一样的,而是说就是同一个字符串对象. 用Java的话来说就是a==b的结果是true. 然而这个只对字符串以及小的整型或者长整型有效. 其它的对象是不会被驻留的,也就是说如果你创建了两个对象而他们的值是相等的,但他们并不是同一个对象.

深入Java内存模型

- - ImportNew
你可以在网上找到一大堆资料让你了解JMM是什么东西,但大多在你看完后仍然会有很多疑问. happen-before是怎么工作的呢. 用volatile会导致缓存的丢弃吗. 为什么我们从一开始就需要内存模型. 通过这篇文章,读者可以学习到足以回答以上所有问题的知识. 它包含两大部分:第一部分是硬件层次的大体架构,第二部分是深入OpenJdk源代码和实现.

Java内存之"栈"与"堆"

- - ITeye博客
        昨天中午,发了一篇 equals和==区别的博文,晚上再看时有几位大牛指出了其中的一些错误,很感谢他们的留言,一句简简单单的留言给了我对这些错误知识点改正的机会. 或许这就是从事互联网行业所提倡的互帮互助的精神吧,因为有分享,有交流,互联网才会发展的如此迅猛. 大牛提的一个观点很好,好的东西可以拿出来分享,错的东西却可能带给别人错误的理解,这一点我确实得向看了我写了一些bug博客的人道个歉.