欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Java堆外內(nèi)存回收原理

堆外內(nèi)存簡(jiǎn)介

DirectByteBuffer 這個(gè)類是 JDK 提供使用堆外內(nèi)存的一種途徑,當(dāng)然常見的業(yè)務(wù)開發(fā)一般不會(huì)接觸到,即使涉及到也可能是框架(如 Netty、RPC 等)使用的,對(duì)框架使用者來說也是透明的。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),云夢(mèng)企業(yè)網(wǎng)站建設(shè),云夢(mèng)品牌網(wǎng)站建設(shè),網(wǎng)站定制,云夢(mèng)網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,云夢(mèng)網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

堆外內(nèi)存優(yōu)勢(shì)

堆外內(nèi)存優(yōu)勢(shì)在 IO 操作上,對(duì)于網(wǎng)絡(luò) IO,使用 Socket 發(fā)送數(shù)據(jù)時(shí),能夠節(jié)省堆內(nèi)存到堆外內(nèi)存的數(shù)據(jù)拷貝,所以性能更高??催^ Netty 源碼的同學(xué)應(yīng)該了解,Netty 使用堆外內(nèi)存池來實(shí)現(xiàn)零拷貝技術(shù)。對(duì)于磁盤 IO 時(shí),也可以使用內(nèi)存映射,來提升性能。另外,更重要的幾乎不用考慮堆內(nèi)存煩人的 GC 問題。

堆外內(nèi)存創(chuàng)建

我們直接來看代碼,首先向 Bits 類申請(qǐng)額度,Bits 類內(nèi)部維護(hù)著當(dāng)前已經(jīng)使用的堆外內(nèi)存值,會(huì) check 當(dāng)前申請(qǐng)的大小與已經(jīng)使用的內(nèi)存大小是否超過總的堆外內(nèi)存大?。J(rèn)大小與堆內(nèi)存差不多,其實(shí)是有細(xì)微區(qū)別的,拿 CMS GC 來舉例,它的大小是新生代的最大值 - 一個(gè) survivor 的大小 + 老生代的最大值),可以使用 -XX:MaxDirectMemorySize 參數(shù)指定堆外內(nèi)存最大大小。

Java 堆外內(nèi)存回收原理

如果 check 不通過,會(huì)主動(dòng)執(zhí)行 System.gc(),然后 sleep 100 毫秒,再進(jìn)行 check,如果內(nèi)存還是不足,就拋出 OOM Error。

如果 check 通過,就會(huì)調(diào)用 unsafe.allocateMemory 真正分配內(nèi)存,返回內(nèi)存地址,然后再將內(nèi)存清 0。題外話,這個(gè) unsafe 命名看著是不是很嚇人,這個(gè) unsafe 不是說不安全,而是 JDK 內(nèi)部使用的類,不推薦外部使用,所以叫 unsafe,Netty 源碼內(nèi)部也有類似命名。

由于申請(qǐng)內(nèi)存前可能會(huì)調(diào)用 System.gc(),所以謹(jǐn)慎設(shè)置 -XX:+DisableExplicitGC 這個(gè)選項(xiàng),這個(gè)參數(shù)作用是禁止代碼中顯示觸發(fā)的 Full GC。

堆外內(nèi)存回收

cleaner = Cleaner.create(this, new Deallocator (base, size, cap));

看到這段代碼從成員的命名上就應(yīng)該知道,是用來回收堆外內(nèi)存的。確實(shí),但是它是如何工作的呢?接下來我們看看 Cleaner 類。

Java 堆外內(nèi)存回收原理

Cleaner 類,內(nèi)部維護(hù)了一個(gè) Cleaner 對(duì)象的鏈表,通過 create(Object, Runnable) 方法創(chuàng)建 cleaner 對(duì)象,調(diào)用自身的 add 方法,將其加入到鏈表中。更重要的是提供了 clean 方法,clean 方法首先將對(duì)象自身從鏈表中刪除,保證只調(diào)用一次,然后執(zhí)行 this.thunk 的 run 方法,thunk 就是由創(chuàng)建時(shí)傳入的 Runnable 參數(shù),也就是說 clean 只負(fù)責(zé)觸發(fā) Runnable 的 run 方法,至于 Runnable 做什么任務(wù)它不關(guān)心。

那 DirectByteBuffer 傳進(jìn)來的 Runnable 是什么呢?

Java 堆外內(nèi)存回收原理

Deallocator 類的對(duì)象就是 DirectByteBuffer 中的 cleaner 傳進(jìn)來的 Runnable 參數(shù)類,我們直接看 run 方法 unsafe.freeMemory 釋放內(nèi)存,然后更新 Bits 里已使用的內(nèi)存數(shù)據(jù)。

接下來我們關(guān)注各個(gè)環(huán)節(jié)是如何串起來的?這里主要講兩種回收方式:一種是自動(dòng)回收,一種是手動(dòng)回收。

如何自動(dòng)回收?

Java 是不用用戶去管理內(nèi)存的,所以 Java 對(duì)堆外內(nèi)存 默認(rèn)是自動(dòng)回收的。它是 由 GC 模塊負(fù)責(zé)的,在 GC 時(shí)會(huì)掃描 DirectByteBuffer 對(duì)象是否有有效引用指向該對(duì)象,如沒有,在回收 DirectByteBuffer 對(duì)象的同時(shí)且會(huì)回收其占用的堆外內(nèi)存。但是 JVM 如何釋放其占用的堆外內(nèi)存呢?如何跟 Cleaner 關(guān)聯(lián)起來呢?

這得從 Cleaner 繼承了 PhantomReference(虛引用) 說起。說到 Reference,還有 SoftReference、WeakReference、FinalReference 他們作用各不相同,這里就不展開說了。

簡(jiǎn)單介紹 PhantomReference,首先虛引用是不會(huì)影響 JVM 去回收其指向的對(duì)象,當(dāng) GC 某個(gè)對(duì)象時(shí),如果有此對(duì)象上還有虛引用對(duì)其引用,會(huì)將 PhantomReference 對(duì)象插入 ReferenceQueue 隊(duì)列。

PhantomReference插入到哪個(gè)隊(duì)列呢?看 PhantomReference 類代碼,其繼承自 Reference,Reference 對(duì)象有個(gè) ReferenceQueue 成員,這個(gè)也就是 PhantomReference 對(duì)象插入的 ReferenceQueue 隊(duì)列,此成員如果不由外部傳入就是 ReferenceQueue.NULL。如果需要通過 queue 拿到 PhantomReference 對(duì)象,這個(gè) ReferenceQueue 對(duì)象還是必須由外部傳入。

Java 堆外內(nèi)存回收原理

Reference 類內(nèi)部 static 靜態(tài)塊會(huì)啟動(dòng) ReferenceHandler 線程,線程優(yōu)先級(jí)很高,這個(gè)線程是用來處理 JVM 在 GC 過程中交接過來的 reference。想必經(jīng)常用 jstack 命令,看線程堆棧的同學(xué)應(yīng)該見到過這個(gè)線程。

我們來看看 ReferenceHandler 是如何處理的?直接看 run 方法,首先是個(gè)死循環(huán),一直在那不停的干活,synchronized 塊內(nèi)的這段主要是交接 JVM 扔過來的 reference(就是 pending),再往下看,很明顯,調(diào)用了 cleaner 的 clean 方法。調(diào)完之后直接 continue 結(jié)束此次循環(huán),這個(gè) reference 并沒有進(jìn)入 queue,也就是說 Cleaner 虛引用是不放入 ReferenceQueue。

Java 堆外內(nèi)存回收原理

這塊有點(diǎn)想不通,既然不放入 ReferenceQueue,為什么 Cleaner 類還是初始化了這個(gè) ReferenceQueue。

如何手動(dòng)回收?

手動(dòng)回收,就是由開發(fā)手動(dòng)調(diào)用 DirectByteBuffer 的 cleaner 的 clean 方法來釋放空間。由于 cleaner 是 private 反問權(quán)限,所以自然想到使用反射來實(shí)現(xiàn)。

Java 堆外內(nèi)存回收原理

還有另一種方法,DirectByteBuffer 實(shí)現(xiàn)了 DirectBuffer 接口,這個(gè)接口有 cleaner 方法可以獲取 cleaner 對(duì)象。

Java 堆外內(nèi)存回收原理

Netty 中的堆外內(nèi)存池就是使用反射來實(shí)現(xiàn)手動(dòng)回收方式進(jìn)行回收的。


很多時(shí)候,我們?cè)趯W(xué)習(xí)一門技術(shù)時(shí)候往往限于眼前而很難突破,也就是通俗意義上的思維固化,這個(gè)時(shí)候你就需要用另一種思維來打破現(xiàn)狀。學(xué)習(xí)的目的在于擴(kuò)寬自己的視野、發(fā)散自己的思維,以更完備的視角去迎接人生的抉擇。

網(wǎng)頁題目:Java堆外內(nèi)存回收原理
網(wǎng)頁URL:http://aaarwkj.com/article26/igigcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、網(wǎng)站維護(hù)、Google響應(yīng)式網(wǎng)站、網(wǎng)站設(shè)計(jì)、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)
亚洲成人av毛片在线观看| 蜜臀91精品视频在线观看| 日韩精品欧美视频久久| 蜜桃福利视频一区二区| 最新免费观看男女啪啪视频| 熟女乱熟乱熟妇综合网二区| 中文字幕精品高清中国| 好吊毛片一区二区三区| 天天操天天干蜜桃av| 18岁以下禁看视频网站| 日韩成人午夜视频在线| 亚州无吗一区二区三区| 九色综合狠狠综合久久| 国产精品天干天综合网| 亚洲精品成人一区不卡| 成年人在线观看免费观看| 日韩av黄色大片在线播看| 五月婷婷六月丁香激情视频| 国产一区二区日本在线| 国产一区二区毛多内射| 国产做a爰片久久91| 国产极品av一区二区三区| 亚洲精品美女久久久久高潮| 国产亚洲一线二线三线| 99精品国产麻豆一区二区三区| 亚洲黄色暴力一区视频| 白浆熟女精品国产91| av免费在线观看麻豆| 久久综合伊人欧美精品| 欧美日韩一区二区三区福利| 尤物视频官网在线观看| 国产亚洲精品久久久久久| 免费高清日本一区二区三区视频| 91欧美精品一区二区| 国产高清剧情在线观看| 亚洲男人av天堂东京热| 日本国产一区二区精品| 久久婷婷精品国产亚洲av| 午夜免费视频观看在线| 亚洲熟女午夜毛片av毛片| 在线不卡日本v二区到六区|