java虛擬機內存模型主要包括:程序計數器、虛擬機棧、本地方法棧、java堆、方法區。
1:程序計數器
程序計數器是一塊很小的內存,每一個線程都必須用一個獨立的程序計數器,用於記錄下一條要運行的指令。各個線程的計數器之間不相互影響,獨立工作,是一個線程的私有的內存模型。
2:java虛擬機棧
java虛擬機棧也是線程私有的內存空間,它和java程序在同一時間創建,它保存方法的局部變量、部分結果,並參與方法的調用和返回。
java虛擬機的允許java棧的大小是動態的或者固定的。java虛擬機拋出兩個異常:StackOverflowError和OutOfMemoryError。
參數配置:
-Xss 設置棧的大小,棧的大小直接決定函數調用的可達深度。
public class testStack {
static int count=0;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
recursion();
} catch (Throwable e) {
// TODO: handle exception
System.out.println("棧的深度是:"+count);
e.printStackTrace();
}
}
public static void recursion()
{
count++;
recursion();
}
}
設置不同的-Xss大小,運行出的深度是不一樣的。
虛擬機棧運行時使用一種叫做棧幀的數據結構保存上下文數據。棧幀存放了方法的局部變量表、操作數棧、動態鏈接方法和返回地址信息,這就說明方法中參數不同使用的棧空間是不同的。
3:本地方法棧
本地方法棧和java棧相似,但它是管理本地方法的調用,本地方法是C實現的。但在sun的hot spot虛擬機中,不區分本地方法和虛擬機棧。同時也拋出兩個異常:StackOverflowError和OutOfMemoryError。
4:java堆
java堆是java運行時內存最重要的部分,幾乎所有的對象和數組都是在堆內存中分配空間。java堆分為新生代和老年代。新生代主要存儲剛剛產生的對象,如果對象的生命足夠長,就把老年對象移入老年代。
新生大分為三級:eden(剛出生)、survivor space0(幸存者0)、survivor space1(幸存者1)。
5:方法區
方法區也是jvm內存區中非常重要的一塊內存區域,它是被jvm所有線程所共享的,方法區主要保存的信息是類的元數據。
在Hot Spot 虛擬機中,方法區稱為永久區。
堆分配參數總結:
- -Xms:設置java應用程序啟動時的初始堆大小
- -Xmx:設置java應用程序能獲得的最大堆大小
- -Xss:設置線程棧的大小
- -XX:MinHeapFreeRatio:設置堆空間的最小空間比例。當堆空間的空閑內存小於這個數值時,jvm便會擴展堆空間。
- -XX:MaxHeapFreeRatio:設置堆空間的最大空間比例。當堆空間的空閑內存大於這個數值時,jvm便會縮小堆空間。
- XX:NewSize : 設置新生代的大小
- XX:NewRatio:設置老年代與新生代的比例,即老年代除以新生代大小
- XX:SurviorRatio:新生代中eden區與survivior 區的比例
- -XX:PermSize:設置永久區的大小
- -XX:TargetSurvivorRatio:設置survivior 的使用率。當達到這個空間使用率時,會將對象送入老年代。