1. 程式人生 > >【Java虛擬機器探究】5.常用JVM配置引數-棧的分配引數

【Java虛擬機器探究】5.常用JVM配置引數-棧的分配引數

在使用JVM編譯java時,都會去設定相關的引數(例如使用eclipse的時候,可以設定eclipse的eclipse.ini檔案來對jvm做一些引數配置)。jvm的引數設定主要涉及到三種,分別是Trace跟蹤引數、堆的分配引數、棧的分配引數。

本章主要講解棧的分配引數的相關資訊。
1.棧大小分配
分配引數:-Xss
特點:
(1)區域性變數、引數都分配在棧上。
(2)棧的記憶體通常只有幾百k,但是它決定了函式呼叫的深度;如果程式使用了很深的遞迴函式,而棧記憶體又非常小,此時很有可能發生棧溢位(java.lang.StackOverflowError)的情況。
(3)每一個執行緒都有獨立的棧空間。如果想盡量多跑一些執行緒的話,就儘量將棧記憶體縮小,而不是增大。

下面是一段遞迴函式的呼叫:
public class TestStackDeep {
	private static int count = 0;
	
	public static void recusion(long a,long b,long c){
		long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10;
		count++;
		recusion(a,b,c);
	}
	
    public static void main(String[] args) {
    	try {
			recusion(0L,0L,0L);
		} catch (Throwable e) {
			System.out.println("deep of calling = "+count);
			e.printStackTrace();
		}
	}
}
在該段程式碼中,我們的遞迴函式每一次都會記錄呼叫的次數,當發生棧溢位的異常時,catch該異常,然後打印出一共遞迴的層數。
首先我們將棧記憶體調整為128k:

最終結果:

可以看到執行了304次遞迴方法,並丟擲java.lang.StackOverflowError棧溢位的異常。

然後我們將棧記憶體調整為256k:

最終結果:

可以看到執行了758次遞迴方法,並丟擲java.lang.StackOverflowError棧溢位的異常。
這說明棧的大小決定了遞迴函式的深度,原因是因為棧需要儲存每一次遞迴函式的區域性變數以及內部引數,當有幾千次遞迴的時候,棧記憶體就儲存了幾千次的區域性變數以及引數,久而久之就會爆棧。所以一般出現java.lang.StackOverflowError棧溢位異常時,通常是因為程式呼叫的層數過深。
如果我們想要在有限的棧記憶體執行一定深度的遞迴函式,此時需要減少在遞迴函式中的區域性變數數、內部引數數量,使得棧記憶體中的棧幀的區域性變量表、以及成員變數引數空間壓力小一些。

至此,有關Trace跟蹤引數、堆的分配引數、棧的分配引數就講解完畢了。當然,jvm的引數調整不僅僅是這些,剩下的引數在後面的jvm模組講解中,會提到。

相關推薦

Java虛擬機器探究5.常用JVM配置引數-分配引數

在使用JVM編譯java時,都會去設定相關的引數(例如使用eclipse的時候,可以設定eclipse的eclipse.ini檔案來對jvm做一些引數配置)。jvm的引數設定主要涉及到三種,分別是Trace跟蹤引數、堆的分配引數、棧的分配引數。本章主要講解棧的分配引數的相關資

Java虛擬機器詳解03----常用JVM配置引數

本文主要內容: Trace跟蹤引數 堆的分配引數 棧的分配引數 零、在IDE的後臺列印GC日誌: 既然學習JVM,閱讀GC日誌是處理Java虛擬機器記憶體問題的基礎技能,它只是一些人為確定的規則,沒有太多技術含量。 既然如此,那麼在I

java虛擬機器系列java中類與物件的載入順序

首先了解一下Java虛擬機器初始化的原理。JVM通過加裝、連線和初始化一個Java型別,使該型別可以被正在執行的Java程式所使用。型別的生命週期如下圖所示: 裝載和連線必須在初始化之前就要完成。 類初始化階段,主要是為類變數賦予正確的初始值。這裡的“正確”初始值指的是程

Java虛擬機器學習記憶體區域

根據《Java虛擬機器規範(Java SE 7)》的規定,Java虛擬機器所管理的記憶體包括如圖所示的幾個執行時資料區域: JVM有兩種機制:一個是裝載具有合適名稱的類(類或是介面),包含類的裝載、連線、初始化的過程叫做類裝載子系統;另外的一個負責執行包含在已裝載的

Java虛擬機器執行緒安全與鎖優化

執行緒安全與鎖優化 絕對執行緒安全 相對執行緒安全 執行緒安全的實現方式 互斥同步 非阻塞同步 鎖優化 參考 絕對執行緒安全 當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行時環境

Java虛擬機器Java記憶體模型與執行緒

Java記憶體模型與執行緒 Java記憶體模型 記憶體間互動操作 volatile關鍵字 Java與執行緒 核心實現 使用使用者執行緒實現 使用使用者執行緒加輕量級程序混合實現 Java執行緒的實現

Java虛擬機器HotSpot即時編譯器優化

HotSpot即時編譯器優化 關於即時編譯器 熱點探測方法 基於取樣的熱點探測 基於計數器的熱點探測 方法呼叫計數器 回邊計數器 編譯優化技術 公共子表示式消除

Java虛擬機器Java前端編譯器

Java前端編譯器 關於編譯器 編譯過程 解析與填充符號表 詞法、語法分析 填充符號表 註解處理器 語義分析與位元組碼生成 標註檢查 資料及控制流分析

Java虛擬機器幀和方法呼叫

棧幀和方法呼叫 執行時棧幀結構 區域性變量表 運算元棧 動態連線 返回地址 方法呼叫 解析 分派 靜態分派 動態分配 虛擬機器動態分配的實現

Java虛擬機器類載入

類載入 類載入的時機 類載入宣告週期 類初始何時進行 類載入的過程 載入 驗證 檔案格式驗證 元資料驗證 位元組碼驗證 符號引用驗證 準

Java虛擬機器類檔案結構

類檔案結構 class檔案是一組8位位元組為基礎單位的二進位制流,各個資料專案嚴格按照順序緊湊地排列在class檔案中,中間沒有新增任何分隔符。遇到需要佔用8位位元組以上空間的資料項時,則會按照高位在前的方式分割成若干個8位位元組進行儲存。 class檔案格式只有兩種資料型別:無

Java虛擬機器垃圾收集器和記憶體分配策略

垃圾收集器和記憶體分配策略 垃圾收集器 Serial 收集器 ParNew 收集器 Parallel Scavenge 收集器 Serial Old 收集器 Parallel Old 收集器 CMS 收集器(C

Java虛擬機器垃圾收集演算法

垃圾收集演算法 垃圾收集演算法 標記 - 清除演算法 複製演算法 標記 - 整理演算法 分代收集演算法 參考 垃圾收集演算法 標記 - 清除演算法 演算法分為兩個階段:標記和清除。首先標

Java虛擬機器finalize() 方法

finalize() 方法 物件的回收需要經歷兩次標記過程:如果物件在進行可達性分析後發現沒有與GC Roots相連線的引用鏈,那麼它將會被第一次標記並且進行一次篩選,篩選的條件就是此物件是否有必要執行finalize() 方法。當物件沒有覆蓋finalize() 方法,或者fina

Java虛擬機器判斷物件是否存活的演算法

判斷物件是否存活的演算法 判斷物件是否存活的演算法 引用計數演算法 可達性分析演算法 參考 判斷物件是否存活的演算法 引用計數演算法 引用計數演算法是這樣的:給物件中新增一個引用計數器,每當一個地方引用

深入理解 Java 虛擬機器筆記虛擬機器位元組碼執行引擎

7.虛擬機器位元組碼執行引擎 執行引擎是 Java 虛擬機器最核心的組成部分之一。在 Java 虛擬機器規範中制定了虛擬機器位元組碼執行引擎的概念模型,這個概念模型成為各種虛擬機器執行引擎的統一外觀(Facade)。不同的虛擬機器實現,執行引擎可能會有解釋執行和編譯執行兩種,有可能兩

深入理解 Java 虛擬機器筆記虛擬機器效能監控與故障處理工具

3.虛擬機器效能監控與故障處理工具 定位問題時,知識和經驗是關鍵基礎、資料(執行日誌、異常堆疊、GC日誌、執行緒快照、堆轉儲快照)是依據、工具是運用知識處理資料的手段。 思維導圖 JDK的命令列工具 jps: 虛擬機器程序狀況工具 jps(JVM Proce

深入理解 Java 虛擬機器筆記類檔案結構

5.類檔案結構 由於最近十年內虛擬機器以及大量建立在虛擬機器之上的程式語言如雨後春筍般出現並蓬勃發展,將我們編寫的程式編譯成二進位制本地機器碼(Native Code)已不再是唯一的選擇,越來越多的程式語言選擇了作業系統和機器指令集無關的、平臺中立的格式作為程式

Java虛擬機器3、虛擬機器物件

--------------------------------【Java虛擬機器】系列-------------------------------- 1、Java技術體系 2、Java記憶體區域 3、虛擬機器物件 4、OutOfMemoryError異常 -

Java虛擬機器4、OutOfMemoryError異常

--------------------------------【Java虛擬機器】系列-------------------------------- 1、Java技術體系 2、Java記憶體區域 3、虛擬機器物件 4、OutOfMemoryError異常 -