博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个Java对象到底有多大
阅读量:5923 次
发布时间:2019-06-19

本文共 2264 字,大约阅读时间需要 7 分钟。

hot3.png

经常遇到一个问题,需要在内存里缓存一批数据来提高效率(避免每次都读取DB)。那问题来了,这些对象到底会占用多大内存呢,这直接决定了可以缓存多少条记录,以及上线之后是否会内存不够等问题。

来看几种解决方法。

#测试

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

  1. 任务管理器
  2. top
  3. Java Runtime类
  4. blabla。。。。

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

import java.util.*;/** * Created by magicalli on 2015/2/3. */public class TestMemory {    static class A {        int a;    }    public static void main(String[] args) throws InterruptedException {        System.out.println("--- Memory Usage ---:");        Runtime rt = Runtime.getRuntime();        //打印总内存大小 //打印空闲内存大小 //打印已用内存大小 单位(字节)        long usedMemory = rt.totalMemory() - rt.freeMemory();        System.out.println("Total Memory= " + rt.totalMemory() + " Free Memory = " + rt.freeMemory() + " Used Memory=" + usedMemory);        // 把你要测试的占用内存的代码放在这里------start--------------        final int N = 100000;        int[] arr = new int[N];        Integer[] arr2 = new Integer[N];        A[] arrA = new A[N];        for (int i = 0; i < N; i++) {            arr[i] = i;//            arr2[i] = i;//            arrA[i] = new A();        }//        List
list = new ArrayList
(); Map
map = new HashMap
();// for (int i = 0; i < N; i++) {// list.add(i);// map.put(i, UUID.randomUUID().toString());// }// System.out.println(map.size()); // 把你要测试的占用内存的代码放在这里------end-------------- long usedMemory2 = rt.totalMemory() - rt.freeMemory(); System.out.println("Total Memory= " + rt.totalMemory() + " Free Memory = " + rt.freeMemory() + " Used Memory=" + usedMemory2); long objMemory = usedMemory2 - usedMemory; System.out.println("object use memory: " + objMemory / 1024 + "k" + " each is: " + objMemory / N); }}

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

#计算

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

还看到另一种计算方式,用的Unsafe,不过感觉没有前面用Instrumentation的好。参考这里

#线上查看

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

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

#refers

Written with .

转载于:https://my.oschina.net/magicly007/blog/392993

你可能感兴趣的文章
如何减少测试提的bug
查看>>
.html与.text的异同
查看>>
C#异步语法糖的苦与甜
查看>>
初识面向过程与面向对象
查看>>
使用selenium遇到java.lang.NoSuchMethodError: org.apache.xpath.XPathContext,排查
查看>>
iOS多线程开发之GCD(死锁篇)
查看>>
三种软件的特点分析
查看>>
webug4.0储存型xss-10
查看>>
Ubuntu14.04配置gcc4.4.4+Qt4.8.4交叉编译环境
查看>>
2802:小游戏
查看>>
程序员英语二三事(1)
查看>>
new、override关键字
查看>>
java总结
查看>>
iphone开发之解决viewWillAppear失效
查看>>
Activity 事件以及如何得到新打开Activity关闭后返回的数据
查看>>
word标题前出现黑块解决方案
查看>>
python中的正则表达式
查看>>
实例 (用到 阻止事件冒泡 event.stopPropagation();)
查看>>
JQ选择器大全
查看>>
Angular2组件开发—表单输入(三)
查看>>