JAVA的記憶體模型及結構
所有的Java開發人員可能會遇到這樣的困惑?我該為堆記憶體設定多大空間呢?OutOfMemoryError的異常到底涉及到執行時資料的哪塊區域?該怎麼解決呢?
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)的一些資訊:堆記憶體的分配,執行緒的數量以及載入的類的個數;
這裡有一份極好的白皮書: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虛擬機器發現;
關於OutOfMemoryError的更多資訊可以檢視:“Troubleshooting Guide for HotSpot VM”, Chapter 3 on “Troubleshooting on memory leaks”
參考連結:
- Provides Java HotSpot information about VM Options and environment variables
-
Troubleshooting Guide for HotSpot VM
An exhaustive guide for memory leaks, system crashes, hangings, loops, signal and exception handling. -
Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning
Ergonomics and tuning goals, generations sizing using VM arguments. -
Thanks for the memory – Understanding how the JVM uses native memory on Windows and Linux
Explains how the memory in the JVM like the heap is memory into the RAM on different operating systems and CPUs (32/64bit). -
Java Micro Edition – Tuning
Describes runtime options to adjust performance in the Java ME edition. It also illustrates the compilation of bytecode into native code. - Summary of Sun’s document “Tuning Garbage collection with the 1.4.2 Hotspot JVM”.
- Discussion about where references and objects are stored in the JVM.
相關文章
- JVM記憶體結構、Java記憶體模型和Java物件模型JVM記憶體Java模型物件
- 淺談JVM記憶體結構 和 Java記憶體模型 和 Java物件模型JVM記憶體Java模型物件
- Java常見知識點彙總(⑱)——Jvm記憶體結構、Java記憶體模型、Java物件模型的區別JavaJVM記憶體模型物件
- Java記憶體模型及volatileJava記憶體模型
- Java的記憶體模型Java記憶體模型
- Java記憶體模型學習總結Java記憶體模型
- Java記憶體模型深度解析:總結Java記憶體模型
- Java 記憶體模型Java記憶體模型
- Java記憶體模型Java記憶體模型
- Java記憶體模型及GC演算法Java記憶體模型GC演算法
- Java記憶體模型,垃圾回收機制,常用記憶體命令及工具Java記憶體模型
- Redis 雜湊結構記憶體模型剖析Redis記憶體模型
- Java記憶體模型FAQ(一) 什麼是記憶體模型Java記憶體模型
- Java記憶體區域和記憶體模型Java記憶體模型
- JMM Java 記憶體模型Java記憶體模型
- Java記憶體模型-(1)Java記憶體模型
- Java物件記憶體模型Java物件記憶體模型
- 探索Java記憶體模型Java記憶體模型
- 理解Java記憶體模型Java記憶體模型
- java記憶體模型及volatile關鍵字Java記憶體模型
- Java記憶體模型(MESI、記憶體屏障、volatile和鎖及final記憶體語義)Java記憶體模型
- java記憶體模型的實現Java記憶體模型
- Java記憶體模型的基礎Java記憶體模型
- 深入理解Java記憶體模型(七)——總結Java記憶體模型
- 記憶體結構記憶體
- Java記憶體模型是什麼,為什麼要有Java記憶體模型,Java記憶體模型解決了什麼問題?Java記憶體模型
- JVM記憶體模型總結JVM記憶體模型
- Java記憶體模型 - 簡介Java記憶體模型
- Java記憶體模型簡介Java記憶體模型
- 淺談Java記憶體模型Java記憶體模型
- java記憶體模型——重排序Java記憶體模型排序
- Java記憶體模型之前奏Java記憶體模型
- Java基礎:記憶體模型Java記憶體模型
- java記憶體垃圾回收模型Java記憶體模型
- Java記憶體模型_基礎Java記憶體模型
- Java記憶體模型_重排序Java記憶體模型排序
- Java記憶體模型_volatileJava記憶體模型
- 同步和Java記憶體模型Java記憶體模型