UDN-企业互联网技术人气社区

板块导航

浏览  : 1108
回复  : 0

[讨论交流] 一个Java对象到底有多大

[复制链接]
呵呵燕的头像 楼主
发表于 2016-11-11 22:09:27 | 显示全部楼层 |阅读模式
  经常遇到一个问题,需要在内存里缓存一批数据来提高效率(避免每次都读取DB)。那问题来了,这些对象到底会占用多大内存呢,这直接决定了可以缓存多少条记录,以及上线之后是否会内存不够等问题。

  来看几种解决方法。

  #测试

  实践是检验真理的唯一标准!比如你要想cache10w条记录,那你就把10w条记录加载到内存,然后看看到底用了多少内存。至于怎么看内存花了多少,你可以

  任务管理器

  top

  Java Runtime类

  blabla。。。。

  我们来看看直接从Java程序里能获取到的Runtime。

  1. import java.util.*;

  2. /**
  3. * Created by magicalli on 2015/2/3.
  4. */
  5. public class TestMemory {
  6.     static class A {
  7.         int a;
  8.     }

  9.     public static void main(String[] args) throws InterruptedException {
  10.         System.out.println("--- Memory Usage ---:");
  11.         Runtime rt = Runtime.getRuntime();
  12.         //打印总内存大小 //打印空闲内存大小 //打印已用内存大小 单位(字节)
  13.         long usedMemory = rt.totalMemory() - rt.freeMemory();
  14.         System.out.println("Total Memory= " + rt.totalMemory() + " Free Memory = " + rt.freeMemory() + " Used Memory=" + usedMemory);

  15.         // 把你要测试的占用内存的代码放在这里------start--------------
  16.         final int N = 100000;
  17.         int[] arr = new int[N];
  18.         Integer[] arr2 = new Integer[N];
  19.         A[] arrA = new A[N];
  20.         for (int i = 0; i < N; i++) {
  21.             arr[i] = i;
  22. //            arr2[i] = i;
  23. //            arrA[i] = new A();
  24.         }
  25. //        List<Integer> list = new ArrayList<Integer>();
  26.         Map<Integer, String> map = new HashMap<Integer, String>();
  27. //        for (int i = 0; i < N; i++) {
  28. //            list.add(i);
  29. //            map.put(i, UUID.randomUUID().toString());
  30. //        }
  31. //        System.out.println(map.size());
  32.         // 把你要测试的占用内存的代码放在这里------end--------------

  33.         long usedMemory2 = rt.totalMemory() - rt.freeMemory();
  34.         System.out.println("Total Memory= " + rt.totalMemory() + " Free Memory = " + rt.freeMemory() + " Used Memory=" + usedMemory2);
  35.         long objMemory = usedMemory2 - usedMemory;
  36.         System.out.println("object use memory: " + objMemory / 1024 + "k" + " each is: " + objMemory / N);
  37.     }
  38. }
复制代码


  上面方法的最大好处就是可以直接获得实际占用内存大小,是比较简单有效的方法。不好的地方就是如果数据量比较小,可能偏差比较大,而且你也不能解释为什么Integer[]比int[]占用内存大很多,关键是专家说:这种内存占用应该是心里算出来的,你还要去run一下程序,明显就low了,还想晋级?再练练吧!所以我们来看看怎么掐指一算!

  #计算

  这个需要了解JVM里的内存分布,知道每个对象都有object header,blabal。这里推荐一篇好文一个Java对象到底占用多大内存?,我就不重复了。

  还看到另一种计算方式,用的Unsafe,不过感觉没有前面用Instrumentation的好。参考这里Java计算一个对象占用内存的大小

  #线上查看

  如果是要查看线上程序哪个对象占用了大量内存(比如分析内存泄露),那么可以使用jmap。

  #相关知识

  你可能需要了解jps,jinfo,打包jar,manifest,查看jvm运行参数等。

  #refers

  http://www.importnew.com/14948.html

  http://www.cnblogs.com/magialmoon/p/3757767.html

  http://www.oschina.net/question/1_4486

  http://blog.csdn.net/bobpauline/article/details/20699233

  http://happyqing.iteye.com/blog/2013639

  http://sunqi.iteye.com/blog/1917802

  http://www.blogjava.net/stone2083/archive/2013/06/08/400410.html

  http://yueyemaitian.iteye.com/blog/2033046

  http://www.ibm.com/developerworks/cn/java/j-lo-jse61/index.html

  http://www.ibm.com/developerworks/cn/java/j-lo-instrumentation/

原文作者:佚名  来源:开发者头条
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部