分享一個新出爐的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 DispatcherAttach 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手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

您可能也會喜歡…