java memory 隨筆

前言:原來(lái)的文章不是md形式,寫(xiě)的也比較亂,現(xiàn)在看看 有點(diǎn)不好意思,就重新修正下。

今天群里分享這個(gè)圖片,又這個(gè)圖片引起了一系列討論,我們隊(duì)jvm的理解都是局限于知其然不知其所以然的階段啊。


image.png

類似的問(wèn)題:
metaspace在不在堆中?
directory memory和native memory關(guān)系?

討論了一堆,記錄下自己的理解,不一定正確。。。


metaspace在不在堆中? 不在。

可以參考這篇文章:深入探究 JVM | 探秘 Metaspace ---雖然年代寫(xiě)的比較久遠(yuǎn),但作者的理解我感覺(jué)哈 是比較準(zhǔn)的。
這個(gè)是jdk1.8的新特性,1.8以前呢,HotSpot JVM堆上有個(gè)永久代,存放類和方法的元數(shù)據(jù)以及常量池。1.8以后呢把永久代移除了,方法區(qū)移至 Metaspace,字符串常量移至 Java Heap。

為啥要這么干?
1 由于 PermGen 內(nèi)存經(jīng)常會(huì)溢出,引發(fā)惱人的 java.lang.OutOfMemoryError: PermGen,因此 JVM 的開(kāi)發(fā)者希望這一塊內(nèi)存可以更靈活地被管理,不要再經(jīng)常出現(xiàn)這樣的 OOM。
我覺(jué)得這個(gè)原因比較實(shí)在,現(xiàn)在比較流行的框架都喜歡用反射,比如spring的aop,一般這種動(dòng)態(tài)代理的類都會(huì)占用方法區(qū)的資源的。
2 移除 PermGen 可以促進(jìn) HotSpot JVM 與 JRockit VM 的融合,因?yàn)?JRockit 沒(méi)有永久代。

一般情況下:設(shè)置Metaspace的參數(shù)-XX:MetaspaceSize -XX:MaxMetaspaceSize 這兩個(gè)參數(shù)的值最好一致,值的大小可以根據(jù)監(jiān)控情況動(dòng)態(tài)的調(diào)整一下。 如果Metaspace由于空間不足引起動(dòng)態(tài)擴(kuò)容,會(huì)引發(fā)FULL GC。

其他兩篇文章參考:
由「Metaspace容量不足觸發(fā)CMS GC」從而引發(fā)的思考
JVM參數(shù)MetaspaceSize的誤解


directory memory和native memory關(guān)系? 可以理解為directory memory是native memory的一部分。

可以參考這篇文章:
JVM的Heap Memory和Native Memory 這篇文章可以先熟悉下概念。

image.png

一次堆外OOM問(wèn)題排查 這篇文章詳細(xì)的說(shuō)了下堆外內(nèi)存OOM及回收方式 而且有樣例,值得一看。

native memory中文叫本地內(nèi)存,狹義的理解下,對(duì)jvm來(lái)說(shuō),就是不受jvm垃圾回收機(jī)制主動(dòng)管理的內(nèi)存就是本地內(nèi)存。
directory memory指的是NIO direct buffer操作的本地內(nèi)存。

需要注意的是DirectBuffer這個(gè)引用是分配在堆上,受gc控制的,而且記錄分配了多少堆外內(nèi)存的參數(shù)在java.nio.Bits類中,如下圖:


image.png

我還讀過(guò)一篇因?yàn)檫@個(gè)參數(shù)造成OOM,其實(shí)本地內(nèi)存并沒(méi)有超限,可惜當(dāng)時(shí)沒(méi)存。
還讀了一篇JVM進(jìn)程無(wú)緣無(wú)故的掛了,后來(lái)看linux日志是本地內(nèi)存用的太多,被操作系統(tǒng)殺死了,可惜也沒(méi)存。

他的回收機(jī)制叫Cleaner機(jī)制,Cleaner實(shí)現(xiàn)了PhantomReference,具體研究下代碼吧,就是如果DirectBuffer被垃圾回收器回收的話,會(huì)通過(guò)通知機(jī)制回收directory memory。

一般給的建議是自己申請(qǐng)的堆外內(nèi)存,不用的時(shí)候最好自己回收下。DirectBuffer接口有個(gè)cleaner()方法可以獲得Cleaner ,調(diào)用Cleaner.clean方法就可以回收堆外內(nèi)存。


2018-12-14補(bǔ)充

最新理解,full gc可以看看gc日志,如果發(fā)生full gc 就會(huì)回收對(duì)yung old permanent區(qū)都進(jìn)行回收


2018-12-26補(bǔ)充 nio buffer用的是內(nèi)核內(nèi)存,主要目的是減少一次從內(nèi)核態(tài)到用戶態(tài)的內(nèi)存拷貝。

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容