Java最大栈深度有多大

无论你是跟同事、同学、上下级、同行、或者面试官讨论技术问题的时候,很容易卷入JVM大型撕逼现场。为了能够让大家从大型撕逼现场中脱颖而出,最近我苦思冥想如何把知识点尽可能呈现的容易理解,方便记忆。于是就开启了这一系列文章的编写。为了让JVM相关知识点能够形成一个体系,arthinking将编写整理一系列的专题,以尽量以图片的方式描述相关知识点,并且最终把所有相关知识点串成了一张图。持续更新中,欢迎大家阅读。有任何错落之处也请您高抬贵手帮忙指正,感谢!

Java运行时数据区域是如何工作的这篇文章我们知道,线程中的 栈结构如下:

image

每个栈帧包含:本地变量表,操作数栈,动态链接,返回地址等东西...

也就是说栈调用深度越大,栈帧就越多,就越耗内存。

1、测试案例

1.1、测试线程栈大小对栈深度的影响

下面我们用一个测试例子来说明:

有如下递归方法:

public class StackTest {

    private int count = 0;

    public void recursiveCalls(String a){
        count++;
        System.out.println("stack depth: " + count);
        recursiveCalls(a);
    }

    public void test(){
        try {
            recursiveCalls("a");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        new StackTest().test();
    }

}

我们设置启动参数

-Xms256m -Xmx256m -Xmn128m -Xss256k

输出内容:

stack depth: 1556
Exception in thread "main" java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)

可以发现,栈深度为1556的时候,就报 StackOverflowError了。

接下来我们调整-Xss线程栈大小为 512k,输出内容:

stack depth: 3249
Exception in thread "main" java.lang.StackOverflowError
    at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)

发现栈深度变味了3249,说明了:

随着线程栈的大小越大,能够支持越多的方法调用,也即是能够存储更多的栈帧。

1.2、测试方法参数个对栈深度的影响

这里我们固定设置-Xss为256k。

我们知道此时的深度为:1556。

接下来我们给方法添加参数:

public class StackTest {

    private int count = 0;

    public void recursiveCalls(String a){
        count++;
        System.out.println("stack depth: " + count);
        recursiveCalls(a);
    }

    public void test(){
        try {
            recursiveCalls("a");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        new StackTest().test();
    }

}

为何要添加参数呢,因为添加参数之后,栈帧中的本地变量表就会增加内容,我们可以尝试使用以下命令查看下Class文件的汇编指令:

javap -v StackTest.class

可以发现recursiveCalls方法的本地变量表的确增加了,对应方法的入参 a:

      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      44     0  this   Lcom/itzhai/jvm/stacks/StackTest;
            0      44     1     a   Ljava/lang/String;

这个时候我们在执行程序看看结果:

stack depth: 1318
Exception in thread "main" java.lang.StackOverflowError
    at java.nio.Buffer.<init>(Buffer.java:201)

可以发现,栈深度由原来的1556编程了1318。

可以得出结论:

局部变量表内容越多,那么栈帧就越大,栈深度就越小。

2、结论

  • 随着线程栈的大小越大,能够支持越多的方法调用,也即是能够存储更多的栈帧;
  • 局部变量表内容越多,那么栈帧就越大,栈深度就越小。

我们在评审写代码的时候,发现了堆栈溢出,可以查看下对应类的本地变量表,是不是太多了,可不可以优化下代码,或者加大下线程栈的大小,以增加栈的深度。

知道了这个,我们下次面试别人的时候也可以问问对方看看了,嘿嘿。

References

What is the maximum depth of the java call stack?


本文为arthinking基于相关技术资料和官方文档撰写而成,确保内容的准确性,如果你发现了有何错漏之处,烦请高抬贵手帮忙指正,万分感激。

大家可以关注我的博客:itzhai.com 获取更多文章,我将持续更新后端相关技术,涉及JVM、Java基础、架构设计、网络编程、数据结构、数据库、算法、并发编程、分布式系统等相关内容。

如果您觉得读完本文有所收获的话,可以关注我的账号,或者点赞的,您的支持就是我写作的动力!关注我的公众号,及时获取最新的文章。


本文作者: arthinking

博客链接: https://www.itzhai.com/jvm/how-stack-frame-can-a-thread-hold.html

Java最大栈深度有多大

版权声明: BY-NC-SA许可协议:创作不易,如需转载,请务必附加上博客链接,谢谢!


image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335