程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 一次GC問題定位,GC問題定位

一次GC問題定位,GC問題定位

編輯:JAVA綜合教程

一次GC問題定位,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有關。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved