精华内容
下载资源
问答
  • 递归导致堆栈溢出

    2019-11-24 08:38:49
    产生原因:当递归深度过大时,不断的调用方法没有返回数据,每次调用都会将方法的临时变量封装为栈帧存入内存栈,等方法返回的时候才会出栈,所以就会出现一直入栈导致爆栈或者内存溢出的情况 解决办法:如果无法...

    递归导致堆栈溢出

    1. 产生原因:当递归深度过大时,不断的调用方法没有返回数据,每次调用都会将方法的临时变量封装为栈帧存入内存栈,等方法返回的时候才会出栈,所以就会出现一直入栈导致爆栈或者内存溢出的情况
    2. 解决办法:如果无法控制递归的深度,就要避免使用递归,可以采用循环+栈结构代替递归的方式
    3. 参考
      聊聊面试必考-递归思想与实战
      如何利用循环代替递归以防止栈溢出
    展开全文
  • 内存溢出(StackOverflowError)的常见原因有哪些? 栈溢出原因就是方法执行时创建的栈帧超过了栈的深度。最有可能的就是方法递归调用产生这种结果。 堆内存溢出(OOM)的常见原因有哪些? OutOfMemoryError: Java ...

    栈内存溢出(StackOverflowError)的常见原因有哪些?

    栈溢出原因就是方法执行时创建的栈帧超过了栈的深度。最有可能的就是方法递归调用产生这种结果。

    堆内存溢出(OOM)的常见原因有哪些?

    • OutOfMemoryError: Java heap space。在创建新的对象时, 堆内存中的空间不足以存放新创建的对象时发生。产生原因:程序中出现了死循环,不断创建对象;程序占用内存太多,超过了JVM堆设置的最大值
    • OutOfMemoryError: unable to create new native thread。产生原因:系统内存耗尽,无法为新线程分配内存;创建线程数超过了操作系统的限制
    • OutOfMemoryError: PermGen space。永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。
    • OutOfMemoryError:GC overhead limit exceeded超过98%的时间都在用来做GC并且回收了不到2%的堆内存。连续多次的GC,都回收了不到2%的极端情况下才会抛出。
    展开全文
  • 栈溢出(StackOverflowError) ...分清内存溢出还是内存泄漏 泄露则看对象如何被 GC Root 引用。 溢出则通过 调大 -Xms,-Xmx参数。 直接内存溢出 无法创建本地线程(OutOfMemoryError:unable to create nat...

    栈溢出(StackOverflowError)
    程序所要求的栈深度过大导致,可以写一个死递归程序触发。
    堆溢出(OutOfMemoryError:Java heap space)
    分清内存溢出还是内存泄漏
    泄露则看对象如何被 GC Root 引用。
    溢出则通过 调大 -Xms,-Xmx参数。
    直接内存溢出
    无法创建本地线程(OutOfMemoryError:unable to create native thread)
    总容量不变,堆内存,非堆内存设置过大,会导致能给线程的内存不足。

    注意每一个方法的上面的虚拟机参数
    一、堆溢出 创建对象时如果没有可以分配的堆内存,JVM就会抛出OutOfMemoryError:java heap space异常。
    堆溢出实例:

    /**
     * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
     */
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        int i=0;
        while(true){
            list.add(new byte[5*1024*1024]);
            System.out.println("分配次数:"+(++i));
        }
    }
    
    

    运行结果:
    分配次数:1
    分配次数:2
    分配次数:3

    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to java_pid2464.hprof …
    Heap dump file created [16991068 bytes in 0.047 secs]

    Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
    at com.ghs.test.OOMTest.main(OOMTest.java:16)

    附:dump文件会在项目的根目录下生成

    从上面的例子我们可以看出,在进行第4次内存分配时,发生了内存溢出。

    二、栈溢出栈空间不足时,需要分下面两种情况处理:
    线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError
    虚拟机在扩展栈深度时无法申请到足够的内存空间,将抛出OutOfMemberError
    附:当前大部分的虚拟机栈都是可动态扩展的。

    1、栈空间不足——StackOverflowError实例

    public class StackSOFTest {
     
        int depth = 0;
     
        public void sofMethod(){
            depth ++ ;
            sofMethod();
        }
     
        public static void main(String[] args) {
            StackSOFTest test = null;
            try {
                test = new StackSOFTest();
                test.sofMethod();
            } finally {
                System.out.println("递归次数:"+test.depth);
            }
        }
    }
    

    执行结果:
    递归次数:982
    Exception in thread “main” java.lang.StackOverflowError
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:8)
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:9)
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:9)
    ……后续堆栈信息省略

    我们可以看到,sofMethod()方法递归调用了982次后,出现了StackOverflowError。

    2、栈空间不足——OutOfMemberError实例
    单线程情况下,不论是栈帧太大还是虚拟机栈容量太小,都会抛出StackOverflowError,导致单线程情境下模拟栈内存溢出不是很容易,不过通过不断的建立线程倒是可以产生内存溢出异常。

    public class StackOOMTest {
     
        public static void main(String[] args) {
            StackOOMTest test = new StackOOMTest();
            test.oomMethod();
        }
     
        public void oomMethod(){
            while(true){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        loopMethod();
                    }
                }).start();;
            }
        }
     
        private void loopMethod(){
            while(true){
     
            }
        }
    }
    
    

    运行结果:
    ……操作系统直接挂掉了

    如果哪位大神能够成功模拟,还望指点一二。

    三、直接内存溢出
    DirectMemory可以通过-XX:MaxDirectMemorySize指定,如果不指定,默认与Java堆的最大值(-Xmx指定)一样。
    NIO会使用到直接内存,你可以通过NIO来模拟,在下面的例子中,跳过NIO,直接使用UnSafe来分配直接内存。

    public class DirectMemoryOOMTest {
     
        /**
         * VM Args:-Xms20m -Xmx20m -XX:MaxDirectMemorySize=10m
         * @param args
         */
        public static void main(String[] args) {
            int i=0;
            try {
                Field field = Unsafe.class.getDeclaredFields()[0];
                field.setAccessible(true);
                Unsafe unsafe = (Unsafe) field.get(null);
                while(true){
                    unsafe.allocateMemory(1024*1024);
                    i++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                System.out.println("分配次数:"+i);
            }
        }
    }
    
    

    运行结果:
    Exception in thread “main” java.lang.OutOfMemoryError
    at sun.misc.Unsafe.allocateMemory(Native Method)
    at com.ghs.test.DirectMemoryOOMTest.main(DirectMemoryOOMTest.java:20)
    分配次数:27953

    无法创建本地线程
    最后我们在来看看java.lang.OutOfMemoryError:unable to create natvie thread这种错误。 出现这种情况的时候,一般是下面两种情况导致的:

    程序创建的线程数超过了操作系统的限制。对于Linux系统,我们可以通过ulimit -u来查看此限制。
    给虚拟机分配的内存过大,导致创建线程的时候需要的native内存太少。
    我们都知道操作系统对每个进程的内存是有限制的,我们启动Jvm,相当于启动了一个进程,假如我们一个进程占用了4G的内存,那么通过下面的公式计算出来的剩余内存就是建立线程栈的时候可以用的内存。线程栈总可用内存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序计数器占用的内存
    通过上面的公式我们可以看出,-Xmx 和 MaxPermSize的值越大,那么留给线程栈可用的空间就越小,在-Xss参数配置的栈容量不变的情况下,可以创建的线程数也就越小。因此如果是因为这种情况导致的unable to create native thread,那么要么我们增大进程所占用的总内存,或者减少-Xmx或者-Xss来达到创建更多线程的目的。

    其中,-Xmx用来设置你的应用程序(不是JVM)能够使用的最大内存数,如果你的程序要花很大内存的话,那就需要修改缺省的设置,比如配置tomcat的时候,如果流量啊程序啊都很大的话就需要加大这个值了,BUT不要大得超过你的机器的内存。

    另一个-Xms用来设置程序初始化的时候内存栈的大小,增加这个值的话你的程序的启动性能会得到提高。不过同样有前面的限制,以及受到-Xmx的限制。

    总结:
    栈内存溢出: 程序所要求的栈深度过大。
    堆内存溢出: 分清内存泄露还是 内存容量不足。泄露则看对象如何被 GC Root 引用,不足则通过调大-Xms,-Xmx参数。
    直接内存溢出: 系统哪些地方会使用直接内存。

    参考:https://blog.csdn.net/weter_drop/article/details/89395462

    展开全文
  • 下面这篇是从网上看到的JVM内存溢出相关的文档,它的内容详尽并且便于理解,因此就转载了。 原作者:CSDN _Shallow 原文链接:https://blog.csdn.net/qq_41170231/article/details/91359505 栈溢出(StackOverflow...

    前言


    下面这篇是从网上看到的JVM内存溢出相关的文档,它的内容详尽并且便于理解,因此就转载了。


    原作者:CSDN _Shallow
    原文链接:https://blog.csdn.net/qq_41170231/article/details/91359505



    栈溢出(StackOverflowError)
    程序所要求的栈深度过大导致,可以写一个死递归程序触发。
    堆溢出(OutOfMemoryError:Java heap space)
    分清内存溢出还是内存泄漏
    泄露则看对象如何被 GC Root 引用。
    溢出则通过 调大 -Xms,-Xmx参数。
    直接内存溢出
    无法创建本地线程(OutOfMemoryError:unable to create native thread)
    总容量不变,堆内存,非堆内存设置过大,会导致能给线程的内存不足。

    注意每一个方法的上面的虚拟机参数
    一、堆溢出 创建对象时如果没有可以分配的堆内存,JVM就会抛出OutOfMemoryError:java heap space异常。
    堆溢出实例:

    /**
     * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
     */
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        int i=0;
        while(true){
            list.add(new byte[5*1024*1024]);
            System.out.println("分配次数:"+(++i));
        }
    }
    

    运行结果:
    分配次数:1
    分配次数:2
    分配次数:3

    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to java_pid2464.hprof …
    Heap dump file created [16991068 bytes in 0.047 secs]

    Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
    at com.ghs.test.OOMTest.main(OOMTest.java:16)

    附:dump文件会在项目的根目录下生成

    从上面的例子我们可以看出,在进行第4次内存分配时,发生了内存溢出。

    二、栈溢出栈空间不足时,需要分下面两种情况处理:
    线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError
    虚拟机在扩展栈深度时无法申请到足够的内存空间,将抛出OutOfMemberError
    附:当前大部分的虚拟机栈都是可动态扩展的。

    1、栈空间不足——StackOverflowError实例

    public class StackSOFTest {
     
        int depth = 0;
     
        public void sofMethod(){
            depth ++ ;
            sofMethod();
        }
     
        public static void main(String[] args) {
            StackSOFTest test = null;
            try {
                test = new StackSOFTest();
                test.sofMethod();
            } finally {
                System.out.println("递归次数:"+test.depth);
            }
        }
    }
    

    执行结果:
    递归次数:982
    Exception in thread “main” java.lang.StackOverflowError
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:8)
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:9)
    at com.ghs.test.StackSOFTest.sofMethod(StackSOFTest.java:9)
    ……后续堆栈信息省略

    我们可以看到,sofMethod()方法递归调用了982次后,出现了StackOverflowError。

    2、栈空间不足——OutOfMemberError实例
    单线程情况下,不论是栈帧太大还是虚拟机栈容量太小,都会抛出StackOverflowError,导致单线程情境下模拟栈内存溢出不是很容易,不过通过不断的建立线程倒是可以产生内存溢出异常。

    public class StackOOMTest {
     
        public static void main(String[] args) {
            StackOOMTest test = new StackOOMTest();
            test.oomMethod();
        }
     
        public void oomMethod(){
            while(true){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        loopMethod();
                    }
                }).start();;
            }
        }
     
        private void loopMethod(){
            while(true){
     
            }
        }
    }
    

    运行结果:
    ……操作系统直接挂掉了

    如果哪位大神能够成功模拟,还望指点一二。

    三、直接内存溢出
    DirectMemory可以通过-XX:MaxDirectMemorySize指定,如果不指定,默认与Java堆的最大值(-Xmx指定)一样。
    NIO会使用到直接内存,你可以通过NIO来模拟,在下面的例子中,跳过NIO,直接使用UnSafe来分配直接内存。

    public class DirectMemoryOOMTest {
     
        /**
         * VM Args:-Xms20m -Xmx20m -XX:MaxDirectMemorySize=10m
         * @param args
         */
        public static void main(String[] args) {
            int i=0;
            try {
                Field field = Unsafe.class.getDeclaredFields()[0];
                field.setAccessible(true);
                Unsafe unsafe = (Unsafe) field.get(null);
                while(true){
                    unsafe.allocateMemory(1024*1024);
                    i++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                System.out.println("分配次数:"+i);
            }
        }
    }
    

    运行结果:
    Exception in thread “main” java.lang.OutOfMemoryError
    at sun.misc.Unsafe.allocateMemory(Native Method)
    at com.ghs.test.DirectMemoryOOMTest.main(DirectMemoryOOMTest.java:20)
    分配次数:27953

    无法创建本地线程
    最后我们在来看看java.lang.OutOfMemoryError:unable to create natvie thread这种错误。 出现这种情况的时候,一般是下面两种情况导致的:

    程序创建的线程数超过了操作系统的限制。对于Linux系统,我们可以通过ulimit -u来查看此限制。
    给虚拟机分配的内存过大,导致创建线程的时候需要的native内存太少。
    我们都知道操作系统对每个进程的内存是有限制的,我们启动Jvm,相当于启动了一个进程,假如我们一个进程占用了4G的内存,那么通过下面的公式计算出来的剩余内存就是建立线程栈的时候可以用的内存。线程栈总可用内存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序计数器占用的内存
    通过上面的公式我们可以看出,-Xmx 和 MaxPermSize的值越大,那么留给线程栈可用的空间就越小,在-Xss参数配置的栈容量不变的情况下,可以创建的线程数也就越小。因此如果是因为这种情况导致的unable to create native thread,那么要么我们增大进程所占用的总内存,或者减少-Xmx或者-Xss来达到创建更多线程的目的。

    其中,-Xmx用来设置你的应用程序(不是JVM)能够使用的最大内存数,如果你的程序要花很大内存的话,那就需要修改缺省的设置,比如配置tomcat的时候,如果流量啊程序啊都很大的话就需要加大这个值了,BUT不要大得超过你的机器的内存。

    另一个-Xms用来设置程序初始化的时候内存栈的大小,增加这个值的话你的程序的启动性能会得到提高。不过同样有前面的限制,以及受到-Xmx的限制。

    总结:
    栈内存溢出: 程序所要求的栈深度过大。
    堆内存溢出: 分清内存泄露还是 内存容量不足。泄露则看对象如何被 GC Root 引用,不足则通过调大-Xms,-Xmx参数。
    直接内存溢出: 系统哪些地方会使用直接内存。

    参考:https://blog.csdn.net/weter_drop/article/details/89395462

    展开全文
  • 01 内存溢出 定义:你要求分配的内存超出了系统能分配的,系统不能满足,于是产生溢出。 02内存泄露 定义:你向系统申请分配内存进行使用,可是使用完成以后却不归还,结果你申请的那块内存你自己也不能访问了,而...
  • 堆栈空间溢出(错误 28)   堆栈内存的一个工作区,会随着程序运行的需要而增长或缩小。此错误有以下的原因和解决方法: 有太多活动的 Function、Sub 或 Property 过程调用。 检查过程的嵌套是否太深,...
  • 【java】递归次数过多导致堆栈溢出

    万次阅读 2018-09-03 23:39:04
    在写一个算法中,由于递归调用次数过多,堆栈溢出。...溢出的意思就是越界,操作系统会给每个进程分配一个最大上限的堆栈空间,如果超过了这个内存空间大小程序就会coredump,就像你创建一个太大的数组会崩溃...
  • 我正在研究一个霍夫曼编码程序,我差不多完成但是我陷入无限递归循环。 有谁知道这出错了?这是我得到的错误:Exception in thread "main" java.lang.StackOverflowErrorat sun.nio.cs.SingleByteEncoder.encodeLoop...
  • 题目:堆栈溢出一般是由什么原因导致的? 答:1.函数调用层次太深。函数递归调用时,系统要在栈中不断保存函数调用时的现场和产生的变量,如果递归调用太深,就会造成栈溢出,这时递归无法返回。再有,当函数调用...
  • iOS 堆栈溢出

    2014-04-23 11:37:00
    但是事实上堆和栈都不是无上限的,过多的递归会导致栈溢出,过多的 alloc 变量会导致堆溢出。 例子 不得不说 Cocoa 的内存管理优化做得挺好的,单纯用 C++ 在 Mac 下编译后执行以下代码,递归 174671 次后挂掉: ...
  • Java内存溢出

    2020-04-25 23:04:22
    java.lang.stackOverFlowError,当前主线程方法的无条件递归调用,方法无法调出来,导致堆栈溢出错误; 内存溢出 java.lang.outOfMemoryError: java heap space java堆空间溢出,创建对象的内存大于堆内存,...
  • 通过设置内存大小解决堆栈溢出

    千次阅读 2019-04-10 21:43:35
    一、Java内存模型 二、 栈溢出(StackOverflowError) 栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口灯信息。局部变量表又包含...
  • c++堆栈溢出的处理(包括递归

    千次阅读 2015-05-14 14:58:45
    本文背景: 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用;根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过...6. 内存管理机制--堆栈 (Stack)   使用场合 操作
  • 1、内存溢出 内存溢出是指程序在申请内存时没有足够的内存空间... (3)递归调用太深,导致堆栈溢出等; (4)内存泄漏最终导致内存溢出; 2、内存泄漏 内存泄漏是指使用new申请内存, 但是使用完后没有使用dele...
  • 内存溢出:不顾堆栈分配的局部数据块大小,向数据块中写入过多数据,导致数据越界,结果覆盖了别的数据。常在递归中发生。 个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家...
  • 堆栈内存溢出的原因无非分为两种 系统的空间确实不够 我们的程序出现了死循环(例如一直递归的调用自己) 很快的排除了第一种情况,因为自己的这个项目纯粹练手,未涉及太多的内存消耗,那么围绕着第二种情况展开...
  • 为什么会堆栈溢出问题?

    万次阅读 2019-04-15 14:34:19
    在一个算法中,如果递归函数调用过多次数,那么就会导致堆栈溢出。 原因就是,操作系统会自动给每个进程分配一个最大栈空间2M,如果超过了这个上限,就会导致递归函数执行终止,所以就会报错。递归就像你一直在往一...
  • 背景知识: 栈存放什么:栈存储运行时声明...栈溢出实现,可以递归调用方法,这样随着栈深度的增加,JVM 维持着一条长长的方法调用轨迹。 堆溢出实现,可以循环创建对象或大的对象; 直到内存不够分配,产生栈溢出。 栈
  • c语言之堆栈溢出问题

    2020-12-05 17:21:42
    1.函数的调用,系统所作的工作 2.函数调用时与内存管理 3.递归函数 4.数组作为形参调用函数时,为什么需要连同数组长度一起传进来
  • 堆栈就是一块内存,操作系统在程序启动的时候已经分配好的,供...堆栈内存使用顺序为从后向前 当使用数据超出堆栈大小时堆栈溢出(如递归数据较大或写错时),导致程序卡住或崩溃 堆栈就是内存(4GB)的草稿纸 ...
  • 递归的缺点就是当排序数据量大时,系统堆栈溢出 递归的实质是在堆栈中不断保存现场,但是现场的数据量是很大的 网上给出了堆栈实现的伪码算法,但是这里面存在很多的BUG 这个程序实现了用递归实现小量数据和用...
  • 参看:Stack Overflow(堆栈溢出) Visual Studio执行出现Stack Overflow,该怎么处理呢? 一、产生原因 Stack Overflow(堆栈溢出)是程序调试中比较麻烦的一种错误。但总结一下,引起这种错误的原因大致就是两种...
  • 快速排序,java.lang.StackOverflowError堆栈溢出异常处理通常情况下,当使用基本快速排序,因为用到递归,方法进栈出栈,当数据量达到一定数目的时候会出现堆栈溢出异常java.lang.StackOverflowError;简单的设置...
  • JVM的内存泄漏与溢出

    2020-11-11 09:26:44
    1.堆栈溢出,异常为java.lang.StackOverflowError,说明:一般是递归未返回,或者循环调用造成 2.方法区溢出,异常为java.lang.OutOfMemoryError,说明:这个异常是由于操作系统没有足够的资源来产生这个线程造成的。...
  • 堆栈溢出(Stack Overflow)的解决方法

    万次阅读 2008-01-20 21:04:00
    堆栈溢出是程序调试中,比较麻烦的一种错误,但不外乎就是递归和变量申请大空间内存;错误时,弹出如下图所示框框:其中,0x7c934ffd的值依具体情况而不同。OxC00000FD是错误标号; 1. 局部数组变量空间太大,如下...
  • 该错误出现的原因一般都是因为不停的循环递归调用。1、虚拟机栈是什么? 栈也叫栈内存,是java虚拟机的内存模型之一。它的生命周期是在线程创建时创建,线程结束而消亡,释放内存。因此是私有的,不可共享 栈存储的...
  • 递归

    2020-01-29 13:56:56
    一、符合运用递归的条件: ...因为不停的函数调用,建立方法栈,若无终止条件,或者超出栈内存,则会溢出 解决方案: 1)确立的正确终止条件 2)限制递归调用的深度,即建立调用深度计数器。 递归中...
  • Java递归

    2020-02-02 22:46:52
    递归的特点:点:因为是重复调用自己了,所以看起来像一个循环,所以为了避免内存溢出系统崩溃,我们需要在方法里加一个返回值判断,用于递归循环的跳出; 递归的缺陷:递归调用会占用大量的系统堆栈,内存耗用多,...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 129
精华内容 51
关键字:

递归堆栈内存溢出