【问题标题】:Heapoverflow instead of Stackoverflow in infinite loop无限循环中的堆溢出而不是堆栈溢出
【发布时间】:2014-12-15 00:17:15
【问题描述】:

在 java 中,当方法调用自身并导致无限循环时,会引发 stackoverflow 错误。当对象在堆内存中初始化时,不应该抛出堆内存溢出错误,因为涉及到调用该方法的对象。? 有没有 heapoverflow 之类的错误?!

【问题讨论】:

    标签: java object stack-overflow heap-memory stack-memory


    【解决方案1】:

    如果 Java 在尝试分配对象时用尽堆空间,则会收到 OutOfMemoryError

    http://docs.oracle.com/javase/7/docs/api/java/lang/OutOfMemoryError.html

    在堆内存中初始化对象时,不应该抛出堆内存溢出错误,因为调用方法涉及对象。?

    如果你有一个无限递归函数,它也从堆中分配一个对象,则有可能首先得到一个 OutOfMemoryError。这取决于对象分配的大小,以及堆和堆栈的大小。

    【讨论】:

      【解决方案2】:

      如果你做

      • 你的筹码量足够大,和/或
      • 您的堆大小足够小,

      您将收到堆溢出错误 (java.lang.OutOfMemoryError),而不是堆栈溢出错误 (java.lang.StackOverflowError)。

      您通常看不到此行为的原因是,默认情况下(取决于 JVM),堆栈大小比堆大小小很多,因此堆栈首先用完。

      您可以通过创建递归方法并尝试使用不同的堆和堆栈大小来进行尝试。例如,以下将执行MyClass,堆大小为 2MB,堆栈大小为 4MB。如果调用MyClass 执行涉及创建对象的无限递归方法,则在遇到StackOverflowError 之前,您一定会遇到OutOfMemoryError

      java -Xms2m -Xmx2m -Xss4m MyClass
      

      【讨论】:

        【解决方案3】:

        你在正确的轨道上。您可以用完堆内存,但它不称为 HeapOverflow。它被称为 OutOfMemoryError。 虽然 HeapOverflow 听起来很吸引人,但并不这么称呼它,因为堆通常有散布在各处的空闲和已分配区域。 另一方面,堆栈只有两个区域,空闲和已分配。当您在堆栈上进行更多分配时,分配的区域会增长到空闲区域。因此,您最终会溢出堆栈。有关堆栈与堆的更多信息here

        下面是堆内存耗尽的例子:

        public class RunOutOfMemory {
            public static void main(String[] args){
                System.out.println("Haven't tried to allocate lots of heap memory.");
                int[][] matrix = new int[100000][100000000];
                System.out.println("A miracle occured.");
            }
        }
        

        剧透警告:您需要大约 4 TB 的内存才能让奇迹发生

        【讨论】:

          猜你喜欢
          • 2017-12-15
          • 1970-01-01
          • 2019-05-18
          • 1970-01-01
          • 1970-01-01
          • 2018-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多