涓€銆佸墠瑷€鑷粠java鍦?.4鐗堟湰浠ュ悗鏈変簡NIO锛岀洿鎺ュ唴瀛樺彉寰楀姝ゆ櫘閬嶃€傚湪NIO涓紝鐩存帴鍐呭瓨鍏呭綋缂撳啿鍖猴紝浣跨敤鏈満鍐呭瓨鑰屼笉鏄爢鍐呭瓨銆傝繖绉嶆柟寮忓噺灏戜簡java鍫嗗拰native鍫嗕箣闂寸殑鏁版嵁鎷疯礉鎿嶄綔锛屼竴瀹氱▼搴︿笂鎻愰珮浜嗘暟鎹紶杈撶殑鏁堢巼銆備絾鏄洿鎺ュ唴瀛樼殑鍒嗛厤鍜屽洖鏀舵€ц兘涓嶉珮锛屾墍浠ヤ笉寤鸿棰戠箒鍒嗛厤鐩存帴鍐呭瓨銆傞€氬父鎴戜滑閫氳繃allocateDirect()鍒嗛厤涓€鍧楃洿鎺ュ唴瀛樸€傝繖瀹為檯涓婃槸鍦ㄥ爢涓婃柊寤轰簡涓€涓狣irectByteBufferjava瀵硅薄锛屽畠鎸囩殑鏄竴鍧楃洿鎺ュ唴瀛樼殑鍦板潃锛坖vm杩涚▼涓殑铏氭嫙鍦板潃锛屽疄闄呯墿鐞嗗湴鍧€鏄€氳繃pagefault寮傚父鍒嗛厤鐨勶級銆備笅闈㈠皢浠嬬粛閫氳繃allocateDirect()鍒嗛厤鐩存帴鍐呭瓨鐨勮繃绋嬩互鍙婄儹鐐规簮鐮佷腑DirectMemory鐨勪竴浜涚粏鑺傘€傜儹鐐规簮鐮佺増鏈负锛歰penjdk11.0.142銆侱irectMemory鍐呭瓨鍒嗛厤娴佺▼鈥?M鐩存帴鍐呭瓨鍙互閫氳繃浠ヤ笅鏂规硶杩涜鍒嗛厤銆侭yteBuffer缂撳啿鍖?ByteBuffer.allocateDirect(1024*1024);鐩存帴杩涘叆allocateDirect()鏂规硶锛屽彲浠ョ湅鍒板疄闄呬笂鏂板缓浜嗕竴涓狣irectByteBuffer瀵硅薄銆俻ublicstaticByteBufferallocateDirect(intcapacity){returnnewDirectByteBuffer(capacity);}鏍稿績鍐呭鍦―irectByteBuffer绫荤殑鏋勯€犲嚱鏁颁腑锛屾簮鐮佸涓嬶細DirectByteBuffer(intcap){//package-private//浣跨敤鐖剁被鏋勯€犲嚱鏁板垵濮嬪寲ByteBufferPointersuper(-1,0,cap,涓婇檺);//鍒ゆ柇鏄惁璁剧疆浜嗗唴瀛樺榻愶紙榛樿false锛塨ooleanpa=VM.isDirectMemoryPageAligned();intps=Bits.pageSize();//濡傛灉鏈缃唴瀛樺榻愶紝鍒欏ぇ灏忎笌cap鍊肩浉鍚宭ongsize=Math.max(1L,(long)cap+(pa?ps:0));//鍐呭瓨鍒嗛厤鐨勪竴浜涙鏌ュ拰鍥炴敹鎿嶄綔Bits.reserveMemory(size,cap);闀垮熀=0;try{//鍒嗛厤鍐呭瓨骞惰繑鍥炵洿鎺ュ唴瀛樺湴鍧€base=unsafe.allocateMemory(size);}catch(OutOfMemoryErrorx){Bits.unreserveMemory(size,cap);鎵攛;}unsafe.setMemory(base,size,(byte)0);if(pa&&(base%ps!=0)){//鍥涜垗浜斿叆鍒伴〉闈㈣竟鐣屽湴鍧€=base+ps-(base&(ps-1));}else{鍦板潃=鍩哄湴;}cleaner=Cleaner.create(this,newDeallocator(base,size,cap));灞炴€?绌猴紱}2.1鍐呭瓨鍒嗛厤鍓嶆鏌ユ牳蹇冩柟娉曟槸Bits.reserveMemory(size,cap);閲岄潰婧愮爜濡備笅锛歴taticvoidreserveMemory(longsize,intcap){if(!memoryLimitSet&&VM.isBooted()){//鑾峰彇鏈€澶х洿鎺ュ唴瀛樺ぇ灏弇axMemory=VM.maxDirectMemory();鍐呭瓨闄愬埗璁剧疆=鐪燂紱}//涔愯涓讳箟鑰咃紒//鍦ㄨ繖涓柟娉曚腑锛屾鏌ユ槸鍚﹁繕鏈夊墿浣欑殑鐩存帴鍐呭瓨绌洪棿if(tryReserveMemory(size,cap)){//濡傛灉杩樻湁绌洪棿鍙互鍒嗛厤锛岀洿鎺ヨ繑鍥烇紱}//鑾峰彇Reference瀵硅薄锛堣繖閲岄渶瑕丷eference鐨勪竴浜涚煡璇嗙偣锛塮inalJavaLangRefAccessjlra=SharedSecrets.getJavaLangRefAccess();//鍦ㄥ府鍔╂帓闃熸寕璧风殑寮曠敤瀵硅薄鏃堕噸璇?/杩欏寘鎷墽琛屾寕璧风殑Cleaner(s)锛屽叾涓寘鎷?/Cleaner(s)閲婃斁鐩存帴缂撳啿鍖哄唴瀛?/灏濊瘯閫氳繃CleanerMemory鐩存帴閲婃斁涓€浜泈hile(jlra.tryHandlePendingReference()){//鍐嶆妫€鏌ュ墿浣欑殑鐩存帴鍐呭瓨瀹归噺if(tryReserveMemory(size,cap)){return;}}//瑙﹀彂VM鐨凴eference澶勭悊//寮哄埗FullGC//鍙互鐪嬪埌锛屾瘮濡傚鏋滅洿鎺ュ唴瀛樿竟璺濇鏌ュけ璐ワ紝灏嗚Е鍙慒ullGCSystem.gc();//鍏锋湁鎸囨暟閫€閬垮欢杩熺殑閲嶈瘯寰幆//锛堣繖缁欎簡VM涓€浜涙椂闂存潵瀹屾垚瀹冪殑宸ヤ綔锛?/鏇村鍦ㄥ惊鐜腑妫€鏌ュ墿浣欑殑鐩存帴鍐呭瓨瀹归噺booleaninterrupted=false;灏濊瘯{闀跨潯鐪犳椂闂?1;int鐫$湢=0;while(true){if(tryReserveMemory(size,cap)){杩斿洖锛泒//MAX_SLEEPS涓?if(sleeps>=MAX_SLEEPS){break;}if(!jlra.tryHandlePendingReference()){try{//姣忎釜寰幆鐨勪紤鐪犳椂闂?2(unit:ms)Thread.sleep(sleepTime);鐫$湢鏃堕棿<<=1;鐫¤++锛泒catch(InterruptedExceptione){interrupted=true;}}}//娌℃湁杩愭皵thrownewOutOfMemoryError("鐩存帴缂撳啿鍐呭瓨");}finally{if(interrupted){//涓嶈鍚炰笅涓柇Thread.currentThread().interrupt();}}}tryReserveMemory(size,cap)fordirectmemorymargin鏌ョ湅婧愮爜濡備笅锛歱rivatestaticbooleantryReserveMemory(longsize,intcap){//-XX:MaxDirectMemorySize闄愬埗鎬诲閲忚€屼笉鏄?/瀹為檯鍐呭瓨浣跨敤锛屽綋缂撳啿鍖烘槸椤甸潰//瀵归綈鏃朵細鏈夋墍涓嶅悓銆傞暱鎬讳笂闄愶紱//totalCapacity璁板綍褰撳墠浣跨敤鐨勭洿鎺ュ唴瀛樼殑澶у皬//濡傛灉瑕佸垎閰嶇殑澶у皬灏忎簬鏈€澶х洿鎺ュ唴瀛樹笌褰撳墠浣跨敤鐨勭洿鎺ュ唴瀛樼殑宸€硷紝鍒欎负鐪?/鍚﹀垯杩斿洖鍋噖hile(cap<=maxMemory-(totalCap=totalCapacity.get())){//閫氳繃CAS灏嗗綋鍓嶄娇鐢ㄧ殑鐩存帴鍐呭瓨澶у皬鏇存柊涓哄綋鍓嶆柊鍊糹f(totalCapacity.compareAndSet(totalCap,totalCap+cap)){//鏇存柊淇濈暀鐨勭洿鎺ュ唴瀛榤emorysize涓哄綋鍓嶆柊鍊紃eservedMemory.addAndGet(size);//璁℃暟鍣ㄩ€掑count.incrementAndGet();杩斿洖鐪燂紱}}杩斿洖鍋囷紱}2.2DirectMemory鐨勯粯璁ゆ渶澶у€兼槸澶氬皯?涓婇潰妫€鏌ュ墿浣欏唴瀛樻椂锛屾渶澶х洿鎺ュ唴瀛樹娇鐢ㄧ殑鏄痬axMemory鍙橀噺鐨勫€硷紝鍏跺湪婧愮爜涓殑鍊煎涓嬶細privatestaticvolatilelongmaxMemory=VM.maxDirectMemory();/***杩欓噷directMemory鍦╒M.java涓畾涔変簡涓€涓潤鎬佸彉閲忥紝寰堝鏄撹瀵间汉锛岃浜?浠ヤ负maxDirectMemory鐨勫ぇ灏忔槸64M锛屽叾瀹炰笉鏄?*/publicstaticlongmaxDirectMemory(){杩斿洖鐩存帴鍐呭瓨锛泒鍏跺疄maxMemory鐨勫€煎苟涓嶆槸64M銆傚鏋滈粯璁や笉璁剧疆锛宮axMemory鐨勫€肩被浼间簬鏈€澶у爢鍐呭瓨澶у皬锛?Xmx璁剧疆鐨勫€硷級銆傚鏋滄垜浠缃甁VM杩愯鏃跺弬鏁?XX:MaxDirectMemorySize=xxx锛宮axMemory灏辨槸鎴戜滑鑷畾涔夌殑鍊笺€傜洿鎺ョ湅鐑偣婧愮爜锛氬湪jvm涓紝-XX:MaxDirectMemorySize灞炴€т細琚浆鎹㈡垚sun.nio.MaxDirectMemorySize灞炴€с€傚鏋滄湭璁剧疆锛屽垯榛樿璁剧疆涓?1銆傚綋jvm鍚姩鏃讹紝浼氳鍙栦笂闈㈣缃殑鍊笺€傚鏋滄槸-1锛宒irectMemory浼氳璁剧疆涓鸿繍琛屾椂鐨勬渶澶у唴瀛橈紙涔熷氨鏄樊涓嶅-Xmx鐨勫€硷級銆俶axMemory()涔熸槸涓€涓猲ative鏂规硶锛屾簮鐮佸涓嬶細鑷充簬涓轰粈涔堣鍑犱箮绛変簬鏈€澶у爢鍐呭瓨鐨勫€硷紝鍏跺疄灏辨槸灏戜簡涓€涓猻urvivorspace銆傝繕鏄湅涓€涓媓otspot鐨勬簮鐮侊紙maxMemory鏄€庝箞璁$畻鐨勶級锛歨otspot涓幏鍙栬繍琛屾椂鍐呭瓨瀵瑰簲鐨勬柟娉曟槸max_capacity()銆傛鏂规硶鐨勫ぇ灏忚绠椾笌鍨冨溇鏀堕泦鍣ㄥ瘑鍒囩浉鍏筹細//鏀堕泦鍫嗙殑鐗瑰畾閫夋嫨銆傞潤鎬丆ollectedHeap*heap(){return_collectedHeap;鍙互鐪嬪埌杩欎釜鐗堟湰鐨刪otspot涓湁8绉嶅瀮鍦炬敹闆嗗櫒銆傚熀浜嶤MS鍨冨溇绠楁硶锛屽彲浠ョ湅鍒癈MS鍨冨溇绠楁硶涓嬬殑鍫嗗ぇ灏忓叾瀹炴槸锛氭柊鐢熶唬鏈€澶у唴瀛樷灂鑰佸勾浠f渶澶х湅鏂扮敓浠f渶澶у唴瀛橈紝a鐨勫ぇ灏忓垢瀛樿€呭疄闄呬笂鍑忓皯浜嗐€傛簮鐮佸涓嬶細璋冭瘯杩囩▼涓彲浠ョ湅涓€涓媘ax_capacity()鏂规硶鐨勮繑鍥炲€笺€愯缃簡-Xmx1g銆戯細鍙互鐪嬪嚭DirectMemory榛樿鏈€澶ф槸(Xmx-1鐨勫ぇ灏忓垢瀛樿€咃級;DirectMemory涓嶈冻浼氬鑷碏ullGC锛涘浜嶨1鍨冨溇鏀堕泦鍣紝max_capacity()锛堥珮浣嶅湴鍧€-鐘舵€佸湴鍧€锛夌殑璁$畻鏂瑰紡涓嶄繚瀛樹竴涓猻urvivor锛?Xmx璁剧疆涓哄灏戝氨鏄灏戙€?.3DirectByteBuffer鐨勫唴瀛樺垎閰嶎€冪湡姝e垎閰嶅唴瀛樼殑鏂规硶鍏跺疄鏄痷nsafe.allocateMemory(size)锛屽畠鏄竴涓猲ative鏂规硶锛歨otspot涓殑瀹炵幇鍦╱nsafe.cpp涓紝婧愮爜濡備笅锛氬叾瀹炲氨鏄簳灞傚氨鏄皟鐢ㄦ搷浣滅郴缁熺殑malloc鍑芥暟杩涜鍐呭瓨鍒嗛厤锛岀劧鍚庤繑鍥炰竴涓唴瀛樺湴鍧€缁檍ava銆?.3.1鎬荤粨鐩存帴鍐呭瓨鐨勪竴鑸垎閰嶈繃绋嬶細new涓€涓狣irectByteBuffer瀵硅薄锛汥irectByteBuffer瀵硅薄鍦ㄥ垵濮嬪寲鍜屾墽琛屾瀯閫犳柟娉曟椂璋冪敤unsafe.allocateMemory(size)鍒嗛厤鍐呭瓨锛屽苟浠ュ唴瀛樺湴鍧€浣滀负杩斿洖缁撴灉锛沯vm璋冪敤鎿嶄綔绯荤粺鐨刴alloc鍑芥暟鍒嗛厤铏氭嫙鍐呭瓨锛堝疄闄呬娇鐢ㄤ腑鍐嶉€氳繃缂洪〉寮傚父鍒嗛厤瀹為檯鐗╃悊鍐呭瓨锛夛紝杩斿洖鍐呭瓨鍦板潃缁檍ava锛涘皢鍐呭瓨鍦板潃淇濆瓨鍒癉irectByteBuffer瀵硅薄鐨勬垚鍛樺彉閲忓湴鍧€涓紝浠ヤ緵鍙傝€冿紱鍥犳锛孌irectByteBuffer鏈韩浣滀负涓€涓猨ava瀵硅薄瀛樺湪浜巎vm鍫嗕腑锛屼絾鎸佹湁瀵筺ative鍐呭瓨鐨勫唴瀛樺湴鍧€鐨勫紩鐢ㄣ€侱irectByteBuffer鍦ㄥ爢涓崰鐢ㄧ殑鍐呭瓨寰堝皯锛屼絾瀹冨緢鍙兘鎸佹湁瀵规湰鏈哄唴瀛樼殑澶ч噺寮曠敤銆?.濡備綍娓呯悊涓嶥irectMemory鍏宠仈鐨勬湰鍦板唴瀛樼敱浜庣洿鎺ュ唴瀛樹笉灞炰簬jvm鍫嗗唴瀛樼殑涓€閮ㄥ垎锛孏C鑲畾鏃犳硶鐩存帴绠$悊杩欏潡鍐呭瓨鍖哄煙锛岄偅涔堢洿鎺ュ唴瀛樺浣曞洖鏀跺唴瀛樺憿锛熶笂闈㈡垜浠凡缁忎簡瑙e埌锛岀洿鎺ュ唴瀛樺叾瀹炴槸閫氳繃鎿嶄綔绯荤粺鐨刴alloc鍑芥暟鍒嗛厤鐨勶紝鎵€浠ュ唴瀛橀噴鏀句篃闇€瑕佽皟鐢ㄦ搷浣滅郴缁熺殑free鍑芥暟銆傚湪java涓紝鍙互閫氳繃unsafe.freeMemory()璋冪敤搴曞眰鐨刦ree鍑芥暟銆傚熀浜庤繖绉嶆€濊矾锛岄噴鏀剧洿鎺ュ唴瀛樺彧鏈変袱绉嶆柟寮忥細鎵嬪姩璋冪敤unsafe.freeMemory()閲婃斁锛宯etty涓殑ByteBuf.release()灏辨槸杩欑鏂瑰紡锛涗娇鐢℅C鏈哄埗鑷姩璋冪敤unsafe.freeMemory()閲婃斁寮曠敤鐨勭洿鎺ュ唴瀛橈紱浠婂ぉ涓昏鎯冲垎浜浜岀鍥炴敹鏂瑰紡锛屽嵆GC杩囩▼涓浣曢噴鏀句笉鍐嶅紩鐢ㄧ殑鐩存帴鍐呭瓨銆傚湪寮€濮嬩箣鍓嶏紝鎮ㄩ渶瑕佷簡瑙d竴浜涘叧浜嶳eference鐨勫墠缃煡璇嗐€傚洜涓洪€氳繃GC闂存帴鍥炴敹鐩存帴鍐呭瓨鐨勬柟娉曞畬鍏ㄥ熀浜嶱hantomReference铏氬紩鐢ㄣ€傝繖閲屾垜鐩存帴璐翠竴涓ぇ浣殑鍗氬锛氥€娿€恓ava.lang.ref銆慞hantomReference & jdk.internal.ref.Cleaner銆嬪湴鍧€锛歨ttps://blog.csdn.net/reliveI...杩欑瘒鏂囩珷鍏ㄩ潰浠嬬粛浜哖hantomReference铏氬紩鐢ㄧ殑鐩稿叧鐭ヨ瘑锛屽湪DirectByteBuffer涓€绔犲氨鍙互浜嗛€氳繃涓嶨C鐨勪氦浜掞紝娓呮櫚鐨勬弿杩颁簡鐩存帴鍐呭瓨鐨勫洖鏀惰繃绋嬨€傜粰鑰佹澘鐐硅禐馃憤銆傝嚦姝わ紝鎴戠煡閬撲簡銆?.1 鍐呭瓨鍒嗛厤鍓嶇殑妫€鏌ャ€嬩负浠€涔堜細鍦˙its.reserveMemory(size,cap)鏂规硶涓皟鐢⊿ystem.gc()杩涜FullGC銆傝繖鏄负浜嗗敖鍙兘鍥炴敹涓嶅彲杈剧殑DirectByteBuffer瀵硅薄锛屽彧鏈夐€氳繃GC鎵嶄細鑷姩瑙﹀彂璋冪敤unsafe.freeMemory()閲婃斁鐩存帴鍐呭瓨銆?/p>
