前言:原來的文章不是md形式更振,寫的也比較亂燎斩,現(xiàn)在看看 有點(diǎn)不好意思羞芍,就重新修正下婴削。
今天群里分享這個(gè)圖片,又這個(gè)圖片引起了一系列討論官疲,我們隊(duì)jvm的理解都是局限于知其然不知其所以然的階段啊乏沸。
類似的問題:
metaspace在不在堆中决记?
directory memory和native memory關(guān)系?
討論了一堆菜拓,記錄下自己的理解瓣窄,不一定正確。纳鼎。俺夕。
metaspace在不在堆中? 不在贱鄙。
可以參考這篇文章:深入探究 JVM | 探秘 Metaspace ---雖然年代寫的比較久遠(yuǎn)劝贸,但作者的理解我感覺哈 是比較準(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 的開發(fā)者希望這一塊內(nèi)存可以更靈活地被管理,不要再經(jīng)常出現(xiàn)這樣的 OOM弄捕。
我覺得這個(gè)原因比較實(shí)在僻孝,現(xiàn)在比較流行的框架都喜歡用反射,比如spring的aop守谓,一般這種動(dòng)態(tài)代理的類都會(huì)占用方法區(qū)的資源的穿铆。
2 移除 PermGen 可以促進(jìn) HotSpot JVM 與 JRockit VM 的融合,因?yàn)?JRockit 沒有永久代斋荞。
一般情況下:設(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 這篇文章可以先熟悉下概念筑辨。
一次堆外OOM問題排查 這篇文章詳細(xì)的說了下堆外內(nèi)存OOM及回收方式 而且有樣例,值得一看幸逆。
native memory中文叫本地內(nèi)存棍辕,狹義的理解下暮现,對jvm來說,就是不受jvm垃圾回收機(jī)制主動(dòng)管理的內(nèi)存就是本地內(nèi)存楚昭。
directory memory指的是NIO direct buffer操作的本地內(nèi)存送矩。
需要注意的是DirectBuffer這個(gè)引用是分配在堆上,受gc控制的哪替,而且記錄分配了多少堆外內(nèi)存的參數(shù)在java.nio.Bits類中栋荸,如下圖:
我還讀過一篇因?yàn)檫@個(gè)參數(shù)造成OOM,其實(shí)本地內(nèi)存并沒有超限凭舶,可惜當(dāng)時(shí)沒存晌块。
還讀了一篇JVM進(jìn)程無緣無故的掛了,后來看linux日志是本地內(nèi)存用的太多帅霜,被操作系統(tǒng)殺死了匆背,可惜也沒存。
他的回收機(jī)制叫Cleaner機(jī)制身冀,Cleaner實(shí)現(xiàn)了PhantomReference钝尸,具體研究下代碼吧,就是如果DirectBuffer被垃圾回收器回收的話搂根,會(huì)通過通知機(jī)制回收directory memory珍促。
一般給的建議是自己申請的堆外內(nèi)存,不用的時(shí)候最好自己回收下剩愧。DirectBuffer接口有個(gè)cleaner()方法可以獲得Cleaner 猪叙,調(diào)用Cleaner.clean方法就可以回收堆外內(nèi)存。
2018-12-14補(bǔ)充
最新理解仁卷,full gc可以看看gc日志穴翩,如果發(fā)生full gc 就會(huì)回收對yung old permanent區(qū)都進(jìn)行回收
2018-12-26補(bǔ)充 nio buffer用的是內(nèi)核內(nèi)存,主要目的是減少一次從內(nèi)核態(tài)到用戶態(tài)的內(nèi)存拷貝锦积。