1. 程式人生 > >踩坑了,JDK8中HashMap依然會死迴圈!

踩坑了,JDK8中HashMap依然會死迴圈!

 

 是否你聽說過JDK8之後HashMap已經解決的擴容死迴圈的問題,雖然HashMap依然說執行緒不安全,但是不會造成伺服器load飆升的問題。

 

然而事實並非如此。少年可曾瞭解一種紅黑樹成環的場景,=v=

 

今日在檢視監控時候發現,某一臺機器load飆升

 

 

 

 

感覺問題不對勁,ssh大法登陸機器,top,top -Hp,jstack,jmap四連擊儲存下來堆疊,cpu使用最高的執行緒,記憶體資訊準備分析。

 

首先檢視使用最耗費cpu的執行緒堆疊資訊

cat stack | grep -i 34670 -C10 --color

 

 

 


我勒個去,HashMap,猜測八成死迴圈了,但是我們使用的JDK8,在8中通過棧封閉的連結串列替換,解決了擴容死迴圈的問題。疑惑,繼續往下看。

 

根據堆疊資訊,root方法是問題所在,點開HashMap原始碼

 

 

 


好嘛,load飆高,程式碼有個for語句,我覺得鐵定死迴圈了,看程式碼情況只可能是兩個紅黑樹節點的父親節點相互引用才可以導致無法走出這個for語句。

 

然而這都是我的猜測,我沒有證據。而且讓我追紅黑樹的程式碼,也是需要耗費大量時間的事情,我需要快速驗證我的猜測。

 

我之前dump下來了堆記憶體資訊,我通過jhat 命令生成html的記憶體資訊頁面

 

 

然後輸入http://localhost:7000檢視

我先找業務程式碼中持有這個HashMap的物件,然後點進去查詢內部資訊

 

 

因為資料都放在table中,點選Table欄位,檢視其內容

 

 

table中存在唯一的一個TreeNode節點,這肯定是已經變成了紅黑樹了


點進去檢視

 

 


點選parent欄位資訊

 

 

0x72745d828與0x72745d7b8兩個TreeNode節點的Parent引用都是對方。

後續打算深入研究一下紅黑樹什麼場景會造成這個原因。

最後,無論什麼併發場景請別使用HashMap,ConcurrentHashmap大