分享一個新出爐的JVM里不痛不癢的BUG(Attach機制相關)_網頁設計
※網頁設計最專業,超強功能平台可客製化
窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。
本文來自: PerfMa技術社區
PerfMa(笨馬網絡)官網
概述
老早之前寫過一篇文章,關於attach機制的,可以看下這篇老文章了解一下JVM源碼分析之Attach機制實現完全解讀,比如大家常用的jstack,jmap等工具的主要原理都和attach機制有關,在JVM里處理這些命令的線程主要是Attach Listener
這個線程,這個線程在JVM里是唯一的,我之前也一直以為是唯一的,但是我們同事最近在做一個線程分析產品的時候,發現我們抓到了多個Attach Listener
線程,這讓我也很疑惑,我第一感覺是不可能,肯定是數據抓錯了,直到親眼看到了兩個同名的Attach Listener
線程我才不得不相信原來還真有這種情況。
問題分析
不過從Attach Listener
的實現來看,它設計的初衷不應該是一個多線程的設計,於是我昨晚上又翻了一遍代碼,發現還真可能存在這種情況。舉個栗子,當我們很多人同時執行jstack的時候,就可能會發生,當然有個前提是之前都沒有做過任何和attach相關的操作。
Attach Listener
線程默認情況下不會在JVM啟動的時候就創建,當然也有一個JVM參數可以指定在JVM啟動的時候就啟動這個線程,這個就不會存在我們今天討論的這個問題了,這個JVM參數是-XX:+StartAttachListener
。
當我們在運行時觸發attach機制的時候,首先會通過Signal Dispatcher
線程來創建Attach Listener
線程,代碼如下:
在上面的圈起來的init方法里會創建Attach Listener
線程,但是在init方法執行之前會通過_initialized
屬性來判斷是否需要創建線程,而_initialized
設置為true是在attach_listener_thread_entry
里,這個是Attach Listener Thread
的entry,也就是當這個線程執行的時候執行的方法。
※台北網頁設計公司這麼多該如何選擇?
網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品
但是在設置_initialized=true
之前,如果有多個請求信號發出了(比如同時又很多jstack命令觸發),可能會創建多個Attach Listener
,因為Signal Dispatcher
和Attach Listener
線程是異步執行的。
問題復現
為了讓效果更明顯,我們可以在hotspot里修改下代碼重新編譯下再跑demo
在上面函數里加上圈起來的這段代碼,表示在設置_initialized
屬性之前停留15s,當進程起來之後,不斷執行jstack <pid>
,最終將會看到有非常多的Attach Listener
線程
其實問題的根本就是有一個空檔期(設置_initialized
為true之前)可能存在多次創建線程的可能。
總結
總的來說,創建Attach Listener
線程是通過Signal Dispatcher
線程來創建的,但是決定Signal Dispatcher
是否可以重複創建Attach Listener
線程的標記是在某個Attach Listener
線程里設置的,如果沒有及時設置該標記,就可能存在創建多個Attach Listener
線程的情況。
一起來學習吧:
PerfMa KO 系列課之 JVM 參數【Memory篇】
實戰:一次疑似內存泄漏的問題排查
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
※推薦評價好的iphone維修中心
擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢