美文网首页
栈溢出 StackOverflowError

栈溢出 StackOverflowError

作者: 王某某的笔记 | 来源:发表于2019-09-18 20:12 被阅读0次

问题

生产环境栈溢出

3282788         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282789         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282790 Exception in thread "pool-250-thread-43" java.lang.StackOverflowError
3282791         at java.util.AbstractCollection.toArray(AbstractCollection.java:183)
3282792         at java.lang.String.split(String.java:2378)
3282793         at com.chedaia.task.address.util.ParkingPointUtil.isGps(ParkingPointUtil.java:32)
3282794         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:406)
3282795         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282796         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282797         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282798         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)
3282799         at com.chedaia.task.address.util.ParkingPointUtil.getPreviewGpsPoint(ParkingPointUtil.java:410)

原因

递归调用次数太多导致
且启动脚本中设置了-Xss

-XX:PermSize=128m -Xss256k 

解决办法

由于涉及到的代码依赖较多,先不改动代码
加大线程栈大小到2m

-XX:PermSize=128m -Xss2m 


线程栈大小与递归次数测试

代码

    public static void main(String[] args) {
        recursion(0);
    }

    public static void recursion(int i) {
        System.out.println(i);
        i++;
        recursion(i);
    }

执行结果

结果:966

此时的栈设置为: -Xss128k

963
964
965
966
Exception in thread "main" java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
    at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
    at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
    at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java

不同栈大小下的递归次数

线程栈大小 递归次数约为
-Xss128k 966
-Xss256k 2467
-Xss512k 5447
-Xss1m 11404
-Xss2m 23323
-Xss3m 35247
-Xss4m 41306

方法中的局部变量会占用栈空间

当递归的方法中定义了一些局部变量时会占用线程栈的空间,从而影响到递归的次数
如将上面的方法稍微修改一下,增加3个局部变量:

    public static void recursion(int i) {
        System.out.println(i);
        long a = 1l;
        long b = 2l;
        long c = a + b;
        i++;
        recursion(i);
    }

在栈大小设置为: -Xss128k 时,结果是:623

620
621
622
623
java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
    at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
    at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)

官方说明

https://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom

您可能遇到线程的默认堆栈大小的问题。在Java SE 6中,Sparc的默认值是32位VM中的512k, 64位VM中的1024k。

在x86 Solaris/Linux上,32位虚拟机中是320k, 64位虚拟机中是1024k。

在Windows上,默认的线程堆栈大小是从二进制文件(java.exe)读取的。在Java SE 6中,这个值在32位VM中是320k,在64位VM中是1024k。

您可以通过使用-Xss选项运行来减小堆栈大小。例如:

java -server -Xss64k

注意,在某些版本的Windows上,操作系统可能使用非常粗的粒度来计算线程堆栈大小。如果请求的大小小于默认大小1K或更大,则将堆栈大小四舍五入到默认大小;否则,堆栈大小将四舍五入为1 MB的倍数。

64k是每个线程允许的最小堆栈空间量。

不显式设置-Xss或-XX:ThreadStackSize时,或者把-Xss或者-XX:ThreadStackSize设为0,就是使用“系统默认值”。

用命令查看

# java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
     intx CompilerThreadStackSize                   = 0                                   {pd product}
     intx ThreadStackSize                           = 1024                                {pd product}
     intx VMThreadStackSize                         = 1024                                {pd product}
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

相关文章

  • java异常

    java. lang. Throwable Error:错误 栈溢出:stackoverflowerror 堆溢出...

  • JVM

    1、一般什么情况会发生栈溢出、堆溢出 栈溢出(StackOverflowError) 1、栈是线程私有的,他的生命...

  • 虚拟机栈溢出

    错误原因:java.lang.StackOverflowError 栈内存溢出 栈溢出产生递归调用,循环遍历是不会...

  • 栈溢出 StackOverflowError

    问题 生产环境栈溢出 原因 递归调用次数太多导致且启动脚本中设置了-Xss 解决办法 由于涉及到的代码依赖较多,先...

  • JVM学习:虚拟机栈-相关面试题

    举例栈溢出的情况?(StackOverflowError) 通过 -Xss 设置栈的大小 调整栈大小,就能保证不出...

  • 词汇量

    StackOverflowError 内存栈溢出 disk 磁盘 content 内容 virtual 虚拟 de...

  • EqualsAndHashCode导致的StackOverflo

    Lombok的注解EqualsAndHashCode导致栈空间溢出 排查 StackOverflowError一般...

  • 方法存在栈中, 栈特点:先进后出,所以递归算法没有设置出口会报栈溢出的错stackoverflowerror

  • Java栈溢出--StackOverflowError

    StackOverflowError原因  Java 里的 StackOverflowError。抛出这个错误表明...

  • StackOverflowError 栈溢出实战

    栈溢出的原因 在解决栈溢出问题之前,我们首先需要知道一般引起栈溢出的原因,主要有以下几点: 是否有递归调用 循环依...

网友评论

      本文标题:栈溢出 StackOverflowError

      本文链接:https://www.haomeiwen.com/subject/hnnkuctx.html