今天的這個案例我以爲應該會讓你漲姿式吧,無論你對JVM有多熟悉,看到這篇文章,應該仍是會有點小驚訝的,不過我以爲這個案例我分享出來,是想表達無論多麼奇怪的現象請必定要追究下去,會讓你慢慢變得強大起來,我對奇怪現象一直充滿好奇,因此你碰到些奇怪的問題也能夠發給我,固然最好是JVM相關的segmentfault
由於編輯比較麻煩,直接以截圖的方式發出來吧
另外附上測試源碼:
這個問題描述其實還挺詳細的,另外還附上了測試代碼,我比較喜歡這種提問題的方式,能夠簡單模擬出問題來,這樣也比較好分析,問題簡化是很重要的一步,這樣能節省不少時間,有些現象甚至都不用描述太多,很快就能抓住點數組
這個問題說白了,就是說有些int[]對象不知道是哪裏來的,因而我拿他的例子跑了跑,好像還真有這麼回事,因而我不斷簡化他的代碼,最終發現int[]對象的多少和線程run方法裏的最後一個byte數組的建立有必定關係。多線程
我以爲不該該啊,byte數組在內存裏明明就是byte數組,和int數組也沒半毛錢關係呀,當時忽然靈光一閃,這估計是由於jmx通訊致使的吧,由於jvisualvm和目標進程通訊,傳遞一些數據也挺正常,由於當時比較忙,因而就回復他了,也許是jmx致使的,要它不要使用visualvm看了,jmx端口也關了,能夠經過jmap -histo來確認下。測試
今天忽然又收到了該同窗的郵件了,他也注意到了和那個byte數組有必定關係
同時他還發現個現象,也就是我要他確認的方式,發現jmap -histo執行的時候,int數組仍是比較多,可是加了live參數以後,降下去了,降下去這個比較好解釋,由於live參數會作一次fgc的動做,把某些死對象給回收掉了spa
我因而拿它的demo又跑了跑,按照下面的步驟進行操做線程
執行到這裏,我就開始懷疑jmap了,難道是由於jmap致使的?因而我開始check jmap的實現,包括JDK和JVM裏的邏輯,我要找到哪裏可能會建立int數組,JDK層面基本能夠忽略,由於實在想不到會有啥邏輯可能會有int數組產生,只是發了個命令給JVM進程而已,因而我重點分析JVM層面的實現,當咱們使用jmap作了一次dump的時候或者gc發生的時候都會走到下面的邏輯
由於GC或者內存dump,都必須對內存作一個遍歷,所以必須先暫停這些Java線程,防止在遍歷內存裏的對象的時候進行內存分配,可是每一個線程分配內存其實都是優先走tlab(每一個線程獨有的一塊在eden裏的小內存塊)的,爲了能快速遍歷對象,而不存在不連續的內存,因而JVM會對tlab作一個填充,填充的正好是int數組對象(從上面代碼得知),將剩下的沒被分配的tlab內存給填滿了,所以在系統運行過程當中其實可能伴隨着不少無用的對象產生,哈哈,看到這裏你是否是豁然開朗?對象
你是否能夠解釋以下問題了?blog
這個案例仍是很是有意思的,上述問題我拋出來給你們,你們能夠到下面留言回答上面的問題,若是沒人回答或者沒有正確的答案,我到時到下面留言補充,看你們的熱情度?歡迎你們轉發給更多的人。進程
歡迎關注 PerfMa 社區,推薦閱讀:
Java多線程知識小抄集(一)
海量鏈接服務端CMS調優記