




下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第JVM分配和回收堆外內(nèi)存的方式與注意點(diǎn)目錄JVM內(nèi)存模型如何分配堆外內(nèi)存第一種方式:ByteBuffer#allocateDirect第二種方式:Unsafe#allocateMemory如何回收堆外內(nèi)存第一種方式:Unsafe#freeMemory第二種方式:JVM回收堆外內(nèi)存注意點(diǎn)注意點(diǎn)1:注意點(diǎn)2:引用總結(jié)
JVM內(nèi)存模型
在JVM中內(nèi)存被分成兩大塊,分別是堆內(nèi)存和堆外內(nèi)存,堆內(nèi)存就是JVM使用的內(nèi)存,而堆外內(nèi)存就是非JVM使用的內(nèi)存,一般是分配給機(jī)器使用的內(nèi)存。
那么整個(gè)內(nèi)存模型如下:
因此在JVM中正常只能分配之際獨(dú)有的內(nèi)存即堆內(nèi)存,而我們知道JVM并不建議開發(fā)者直接操作堆外內(nèi)存的,因此容易造成內(nèi)存泄漏,并且難以排查,但是在JVM中是可以操作堆外內(nèi)存的并且也可以回收堆外內(nèi)存,但是是一種不建議的方式。
如何分配堆外內(nèi)存
那么在堆內(nèi)存中如何分配堆外內(nèi)存呢?
在Java中存在兩種方式分配堆外內(nèi)存,分別是ByteBuffer#allocateDirect和Unsafe#allocateMemory。
可能第一個(gè)會(huì)經(jīng)常使用到,這是JavaNIO提供的一個(gè)分配內(nèi)存的類,在做網(wǎng)絡(luò)開發(fā)時(shí)會(huì)經(jīng)常使用該方式進(jìn)行分配內(nèi)存,而第二種方式是Unsafe的方式,我們知道Unsafe是一種不安全的類,該類是提供給開發(fā)者操作最底層數(shù)據(jù)的類,類似C或者C++直接操作內(nèi)存的方式,因此該類并不建議使用,如果使用該類分配內(nèi)存但是沒有及時(shí)回收容易造成內(nèi)存泄漏。
第一種方式:ByteBuffer#allocateDirect
該類分配內(nèi)存的實(shí)現(xiàn)方式如下:
//分配10M的內(nèi)存
ByteBufferbyteBuffer=ByteBuffer.allocateDirect(10*1024*1024);
通過該方式分配堆外內(nèi)存其實(shí)最底層還是使用的是Unsafe#allocateMemory進(jìn)行分配內(nèi)存,ByteBuffer只是對(duì)Unsafe做了一層封裝。
第二種方式:Unsafe#allocateMemory
publicclassTest{
privatestaticUnsafeunsafe=null;
publicstaticvoidmain(String[]args)throwsNoSuchFieldException,IllegalAccessException{
//分配10M的內(nèi)存
FieldgetUnsafe=Unsafe.class.getDeclaredField("theUnsafe");
getUnsafe.setAccessible(true);
unsafe=(Unsafe)getUnsafe.get(null);
//分配完內(nèi)存返回內(nèi)存的地址
longaddress=unsafe.allocateMemory(10*1024*1024);
該方式中Unsafe類并不能直接被使用,但是可以通過反射的方式使用該類,該類分配內(nèi)存后需要手動(dòng)回收,不然被分配的內(nèi)存不會(huì)被釋放。
如何回收堆外內(nèi)存
說(shuō)完了如何分配內(nèi)存,那么繼續(xù)了解如何回收堆外內(nèi)存。
第一種方式:Unsafe#freeMemory
分配堆外內(nèi)存的兩種方式中,第二種Unsafe的方式其實(shí)提供了一個(gè)釋放堆外內(nèi)存的實(shí)現(xiàn),實(shí)現(xiàn)如下:
publicclassTest{
privatestaticUnsafeunsafe=null;
publicstaticvoidmain(String[]args)throwsNoSuchFieldException,IllegalAccessException{
//分配10M的內(nèi)存
FieldgetUnsafe=Unsafe.class.getDeclaredField("theUnsafe");
getUnsafe.setAccessible(true);
unsafe=(Unsafe)getUnsafe.get(null);
//分配完內(nèi)存返回內(nèi)存的地址
longaddress=unsafe.allocateMemory(10*1024*1024);
//回收分配的堆外內(nèi)存
unsafe.freeMemory(address);
在Unsafe中提供了freeMemory的實(shí)現(xiàn)進(jìn)行回收堆外內(nèi)存,但是前提是需要知道被分配的堆外內(nèi)存地址才可以實(shí)現(xiàn)對(duì)應(yīng)的內(nèi)存回收。
這種回收堆外內(nèi)存的方式其實(shí)是開發(fā)者自己手動(dòng)回收,并不是由JVM引起的內(nèi)存回收,那么JVM如何回收堆外內(nèi)存呢?
第二種方式:JVM回收堆外內(nèi)存
通過ByteBuffer#allocateDirect分配的堆外內(nèi)存在JVM中其實(shí)也是存在一定的內(nèi)存占用的,具體關(guān)聯(lián)關(guān)系如下:
當(dāng)通過ByteBuffer#allocateDirect分配堆外內(nèi)存后,會(huì)將堆外內(nèi)存的地址、大小等信息通過DirectByteBuffer進(jìn)行關(guān)聯(lián),那么堆內(nèi)存中就可以關(guān)聯(lián)到堆外內(nèi)存。
那么Cleaner又是什么東西呢?
了解Cleaner需要知道JVM中四種引用方式:強(qiáng)引用、弱引用、軟引用、虛引用,Cleaner就是虛引用的實(shí)現(xiàn),上圖中的ReferenceQueue就是一個(gè)引用隊(duì)列,將需要回收的Cleaner放入到該隊(duì)列中,實(shí)現(xiàn)邏輯如下:
JVM執(zhí)行FullGC時(shí)會(huì)將DirectByteBuffer進(jìn)行回收,回收之后Clearner就不存在引用關(guān)系再下一次發(fā)生GC時(shí)會(huì)將Cleaner對(duì)象放入ReferenceQueue中,同時(shí)將Cleaner從鏈表中移除最后調(diào)用unsafe#freeMemory清除堆外內(nèi)存
那么可能會(huì)存在疑問,為什么DirectByteBuffer會(huì)被回收呢?
首先DirectByteBuffer是存在堆內(nèi)存中的對(duì)象,那么既然存在堆內(nèi)存中就會(huì)發(fā)生GC晉級(jí),即晉升到老年代中,在老年代中就會(huì)發(fā)生FullGC或者OldGC。
注意點(diǎn)
注意點(diǎn)1:
在實(shí)際使用DirectByteBuffer時(shí)要避免把內(nèi)存使用完,但是在實(shí)際操作中我們可能不知道堆外內(nèi)存還剩余多少,因此我們可以在JVM中通過參數(shù)控制,通過JVM參數(shù)-XX:MaxDirectMemorySize指定堆外內(nèi)存的上限大小,當(dāng)超過指定的內(nèi)存上限大小時(shí),會(huì)主動(dòng)觸發(fā)一次FullGC進(jìn)行回收內(nèi)存。
注意點(diǎn)2:
通過DirectByteBuffer分配內(nèi)存時(shí),可能會(huì)出現(xiàn)分配內(nèi)存不夠的情況,因此JVM如果發(fā)現(xiàn)堆外內(nèi)存分配不足時(shí),也會(huì)主動(dòng)發(fā)起一次GC,只不過這次GC是
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 922F挖掘機(jī)斗桿載荷測(cè)試與疲勞試驗(yàn)載荷譜編制研究
- 廣汽本田中日口譯實(shí)踐報(bào)告
- 工業(yè)互聯(lián)網(wǎng)平臺(tái)自然語(yǔ)言處理技術(shù)在智能生產(chǎn)調(diào)度優(yōu)化中的應(yīng)用報(bào)告
- 學(xué)前教育信息化2025年市場(chǎng)潛力報(bào)告:數(shù)字教育產(chǎn)品在學(xué)前教育市場(chǎng)的拓展空間
- T/DZJN 34-2021退役動(dòng)力電池拆解放電技術(shù)與安全規(guī)范
- 高端工業(yè)自動(dòng)化解決方案行業(yè)深度調(diào)研及發(fā)展項(xiàng)目商業(yè)計(jì)劃書
- 郵政儲(chǔ)蓄A(yù)I應(yīng)用企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力項(xiàng)目商業(yè)計(jì)劃書
- 高精度重量傳感器企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力項(xiàng)目商業(yè)計(jì)劃書
- 納米壓印技術(shù)企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力項(xiàng)目商業(yè)計(jì)劃書
- 鄉(xiāng)村手繪瓷器企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力項(xiàng)目商業(yè)計(jì)劃書
- 低齡兒童齲的臨床管理專家共識(shí)
- 2023年生藥學(xué)應(yīng)考試題庫(kù)有答案
- 公共機(jī)構(gòu)節(jié)能量保證型、能用費(fèi)用托管型合同能源管理項(xiàng)目合同文本模板示例
- 普魯士藍(lán)類正極材料未來(lái)可期
- 智能嚇數(shù)紙培訓(xùn)手冊(cè)
- 未帶有效居民身份證考生承諾書
- 原子分光光度法測(cè)定水中重金屬鎘的含量
- 學(xué)生實(shí)習(xí)安全及突發(fā)事件應(yīng)急預(yù)案
- 新教材高一必修下冊(cè)《游園》教案
- DIN1783厚度在0.35mm以上冷軋的鋁及鋁塑性合金帶材和板材、尺寸
- 低風(fēng)險(xiǎn)FOF產(chǎn)品方案設(shè)計(jì)目標(biāo)最大回撤3%以內(nèi)的投資策略
評(píng)論
0/150
提交評(píng)論