JAVA的記憶體模型及結構

來源:互聯網
上載者:User

標籤:

所有的Java開發人員可能會遇到這樣的困惑?我該為堆記憶體設定多大空間呢?OutOfMemoryError的異常到底涉及到運行時資料的哪塊地區?該怎麼解決呢?

Java記憶體模型

Java記憶體模型在JVM specification, Java SE 7 Edition, and mainly in the chapters “2.5 Runtime Data Areas” and “2.6 Frames”中有詳細的說明。對象和類的資料存放區在3個不同的記憶體地區:堆(heap space)、方法區(method area)、本地區(native area)。

堆記憶體存放對象以及數組的資料,方法區存放類的資訊(包括類名、方法、欄位)、靜態變數、編譯器編譯後的代碼,本地區包含線程棧、本地方法棧等存放線程

 

方法區有時被稱為持久代(PermGen)。

所有的對象在執行個體化後的整個運行周期內,都被存放在堆記憶體中。堆記憶體又被劃分成不同的部分:伊甸區(Eden),倖存者地區(Survivor Sapce),老年代(Old Generation Space)。

方法的執行都是伴隨著線程的。原始類型的本地變數以及引用都存放線上程棧中。而引用關聯的對象比如String,都存在在堆中。為了更好的理解上面這段話,我們可以看一個例子:

01 import java.text.SimpleDateFormat;
02 import java.util.Date;
03  
04 import org.apache.log4j.Logger;
05  
06 public class HelloWorld {
07     private static Logger LOGGER = Logger.getLogger(HelloWorld.class.getName());
08  
09     public void sayHello(String message) {
10         SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.YYYY");
11         String today = formatter.format(new Date());
12         LOGGER.info(today + ": " + message);
13     }
14 }

這段程式的資料在記憶體中的存放如下:

通過JConsole工具可以查看運行中的Java程式(比如Eclipse)的一些資訊:堆記憶體的分配,線程的數量以及載入的類的個數;

  Java記憶體結構

這裡有一份極好的白皮書:Memory Management in the Java HotSpot Virtual Machine。它描述了記憶體回收(GC)觸發的記憶體自動管理。Java的記憶體結構包含如下部分:

堆記憶體

堆記憶體同樣被劃分成了多個地區:

  • 包含伊甸(Eden)和倖存者地區(Survivor Sapce)的新生代(Young generation)
  • 老年代(Old Generation)

不同地區的存放的對象擁有不同的生命週期:

  • 建立(New)或者短期的對象存放在Eden地區;
  • 倖存的或者中期的對象將會從Eden地區拷貝到Survivor地區;
  • 始終存在或者長期的對象將會從Survivor拷貝到Old Generation;

生命週期來劃分對象,可以消耗很短的時間和CPU做一次小的記憶體回收(GC)。原因是跟C一樣,記憶體的釋放(通過銷毀對象)通過2種不同的GC實現:Young GC、Full GC。

為了檢查所有的對象是否能夠被銷毀,Young GC會標記不能銷毀的對象,經過多次標記後,對象將會被移動到老年代中。

哪兒的OutOfMemoryError

對記憶體結構清晰的認識同樣可以協助理解不同OutOfMemoryErrors:

Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space

原因:對象不能被分配到堆記憶體中

Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space

原因:類或者方法不能被載入到老年代。它可能出現在一個程式載入很多類的時候,比如引用了很多第三方的庫;

Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

原因:建立的數組大於堆記憶體的空間

Exception in thread “main”: java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?

原因:分配本地分配失敗。JNI、本地庫或者Java虛擬機器都會從本地堆中分配記憶體空間。

Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stack trace>(Native method)

原因:同樣是本地方法記憶體配置失敗,只不過是JNI或者本地方法或者Java虛擬機器發現;

JAVA的記憶體模型及結構

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.