zoukankan      html  css  js  c++  java
  • 一次GC问题定位

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

            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有关。

  • 相关阅读:
    nvidia显卡驱动问题 MKY
    记一次阿里云硬盘LVM的扩容
    大佬的ELK优化总结
    Spring boot使用Javax.validation和ControllerAdvice来进行参数校验
    esbuild 学习(1)
    git push、git pull 需要输入用户名和密码
    redis 发布订阅
    .NET Core使用RabbitMQ
    Nginx配置Https(详细、完整)
    dotnetcore 在线源码
  • 原文地址:https://www.cnblogs.com/white-ink/p/5655017.html
Copyright © 2011-2022 走看看