[转载] java虚拟机 jvm 出入java栈 栈空间内存分配
參考鏈接: Java虛擬機(jī)(JVM)堆棧區(qū)域
java棧空間是一塊線(xiàn)程私有的內(nèi)存空間,java堆和程序數(shù)據(jù)密切相關(guān),那么java棧就是和線(xiàn)程執(zhí)行密切相關(guān)。線(xiàn)程最基本的執(zhí)行行為就是函數(shù)的調(diào)用。每次函數(shù)調(diào)用其實(shí)是通過(guò)java棧傳遞數(shù)據(jù)的。?
數(shù)據(jù)結(jié)構(gòu)中的棧的特性:先進(jìn)后出,后進(jìn)先出。FIFO.?
java內(nèi)存中的棧跟數(shù)據(jù)結(jié)構(gòu)中的特性相似也是FIFO.但是只支持進(jìn)棧和出棧操作。?
java棧中保存的主要內(nèi)容是棧幀。每一次函數(shù)調(diào)用都會(huì)有對(duì)應(yīng)的棧幀被壓進(jìn)去java棧,執(zhí)行完畢的時(shí)候被彈出java棧。如下圖所示。?
??
?
函數(shù)1對(duì)應(yīng)棧幀1,函數(shù)2對(duì)應(yīng)棧幀2.函數(shù)3對(duì)應(yīng)棧幀3.以此類(lèi)推。?
函數(shù)1調(diào)用函數(shù)2,函數(shù)2調(diào)用函數(shù)3,函數(shù)3調(diào)用函數(shù)4,以此類(lèi)推。?
函數(shù)1被調(diào)用的時(shí)候棧幀1入棧,函數(shù)2被調(diào)用的時(shí)候棧幀2入棧,以此類(lèi)推。?
所以最后被調(diào)用的函數(shù)在棧頂,也是最先被彈出棧的。?
每一個(gè)棧幀保存著函數(shù)的局部變量、中間運(yùn)算結(jié)果等數(shù)據(jù)。?
函數(shù)返回的時(shí)候,棧幀從java棧彈出。什么時(shí)候函數(shù)返回呢?兩種情況:?
1.正常的return的時(shí)候。?
2.程序拋出異常。?
在一個(gè)棧幀內(nèi),至少包含局部變量表、操作數(shù)幀和幀數(shù)據(jù)區(qū)幾部分。?
思考的問(wèn)題:沒(méi)一次函數(shù)調(diào)用生成棧幀,從而肯定會(huì)占用一定的棧空間。所以棧空間內(nèi)存不足的時(shí)候,函數(shù)調(diào)用無(wú)法進(jìn)行。當(dāng)請(qǐng)求的棧深度大于最大棧深度的時(shí)候系統(tǒng)會(huì)拋出StackOverflowError異常。(內(nèi)存溢出會(huì)在以后的章節(jié)深入的講解和匯總)?
java虛擬機(jī)制定線(xiàn)程的最大棧空間參數(shù)為-Xss,這個(gè)參數(shù)決定了函數(shù)調(diào)用的最大深度。?
下面一段代碼說(shuō)明,是一個(gè)沒(méi)有出口的遞歸。這段代碼可能會(huì)棧溢出錯(cuò)誤。如下所示:?
?
private static int count=0;
public static void recursion(){
count++;
recursion();
}
public static void main(String[] args) {
try {
recursion();
} catch (Exception e) {
System.out.println("deep of calling="+count);
e.printStackTrace();
}
}
?
?
?
使用參數(shù)-Xss128K執(zhí)行代碼,結(jié)果如下:?
?
deep of calling=2020
Exception in thread "main" java.lang.StackOverflowError
at cn.xhgg.test.TestStackDeep.recursion(TestStackDeep.java:6)
?
?
?
使用參數(shù)-Xss256K執(zhí)行代碼,結(jié)果如下:?
?
count=3665
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
?
?
?
兩次內(nèi)存不同對(duì)比:?
內(nèi)存增大很明顯調(diào)用次數(shù)增加了。?
結(jié)論:?
函數(shù)嵌套的層數(shù)很大程度上有棧的大小決定的。棧越大,函數(shù)調(diào)用的次數(shù)就越多。?
什么因素影響函數(shù)在棧中內(nèi)存大大小呢?下一個(gè)章節(jié)介紹(java虛擬機(jī)jvm局部變量表)
總結(jié)
以上是生活随笔為你收集整理的[转载] java虚拟机 jvm 出入java栈 栈空间内存分配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android 自定义菜单栏,GitHu
- 下一篇: 查询空缺_携程旅行2021校招开启,9大