码迷,mamicode.com
首页 > 其他好文 > 详细

一次GC问题定位

时间:2016-07-09 01:59:18      阅读:302      评论:0      收藏:0      [点我收藏+]

标签:

同事有段代码执行时间过长,需要进行优化,

        Hashmultimap<Int,Bean> map = ...;
        for (400w*96)
        {
            // 计算过程
            Bean = doCompute();
            // 缓存计算结果
            map.put(int,Bean);
        }

  刚开始以为是计算过程doCompute效率低造成的,所以想各种方法优化计算,提前计算、多线程、。。。。等等等等,最终如下

        // 多线程计算
        ....
        // 计算结果放入队列
        ConcurrentLinkedQueue queue = ...;
        queue.offer(doCompute());
        .....
        
        // 队列数据放入缓存
        Hashmultimap<Int,Bean> map = ...;
        map.put(int,queue.poll());

但还是不行,跑跑就cpu 100%,找不到什么原因,直到快下班时突然想到是不是内存引起的,然后放到服务器上一执行,-Xms20G -Xmx20G,没有任何问题。

分析了下,找到了原因(纯分析,下周打印下jvm日志验证下):

对于Hashmultimap和ConcurrentLinkedQueue来说,因为是循环单个放入缓存,所以jvm是逐渐到达最大堆栈的,而一旦jvm发现内存不够用,就启动GC过程,但GC结束发现还是不够用(因为没有实例需要回收)就又启动GC,。。。,循环往复,业务代码不能跑,CPU全被GC占满,而且也不抛内存溢出的异常。

问题定位过程曲折:先入为主容易钻死胡同、好为人师的人真nm多、要相信jvm的计算生产水平。。。。

另外,记录下一些可能用到的知识:

JVM初始分配的内存默认是物理内存的1/64,默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,-XX:MinHeapFreeRatio=40.

JVM最大分配的内存默认是物理内存的1/4,默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制,-XX:MaxHeapFreeRatio=70.

通过free查看到的空闲内存不能完全分配到jvm,能分配的比例应该和jvm厂商、os有关。

一次GC问题定位

标签:

原文地址:http://www.cnblogs.com/white-ink/p/5655017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!