1. 程式人生 > >java之堆外記憶體

java之堆外記憶體

我們都知道java有堆記憶體即Hotspot,堆記憶體是java語言別與其他語言的優勢之一,堆記憶體完全由JVM負責分配和釋放,如果程式沒有缺陷程式碼導致記憶體洩露。程式設計師不需要像寫C++那樣考慮什麼時候該釋放記憶體,java中,你只管建立物件,回收記憶體的事情交給GC。
就像人們一直吃著精米細米一段時間後,又惦記著五穀雜糧了。又想自己控制記憶體的分配,回收了。故而還有一個不常用的堆外記憶體,彌補這部分的不足。
使用堆外記憶體,是為了能直接分配和釋放記憶體,提高效率。JDK5.0之後,程式碼中能直接操作本地記憶體的方式有2種:使用未公開的Unsafe和NIO包下ByteBuffer。但是,堆外記憶體幾乎是不受GC的管理的,也就是說,需要使用者自己呼叫System.gc()進行記憶體的釋放。
下面是NIO包下ByteBuffer的一個例子:

import java.nio.ByteBuffer;
public class DirectHotspotTest{
	public static void main(String[] args) throws Exception{
		while(true){
		 ByteBuffer buffer = ByteBuffer.allocateDirect(10*1024*1024);//一直開闢堆外記憶體
		}
	}
}

上面例子我們是讓程式一直在開闢堆外記憶體,可在一臺配置不是很高的機器上試驗;開啟虛擬機器監控堆記憶體,發現堆記憶體空間非常充足,但是到最後依然會卡死。是因為這個程式使用的是堆記憶體之外的主機的實體記憶體,堆外記憶體不受GC的監控,GC不會對這些記憶體做Full GC操作,所以最終會撐爆主機的實體記憶體而卡死。

總結

堆外記憶體的好處是:

(1)可以擴充套件至更大的記憶體空間。比如超過1TB甚至比主存還大的空間;

(2)理論上能減少GC暫停時間;

(3)可以在程序間共享,減少JVM間的物件複製,使得JVM的分割部署更容易實現;

(4)它的持久化儲存可以支援快速重啟,同時還能夠在測試環境中重現生產資料

站在系統設計的角度來看,使用堆外記憶體可以為你的設計提供更多可能。最重要的提升並不在於效能,而是決定性的

參考:https://www.cnblogs.com/moonandstar08/p/5107648.html