当没有足够的内存来抛出OutOfMemoryError时会发生什么? [英] What happens when there's insufficient memory to throw an OutOfMemoryError?

查看:137
本文介绍了当没有足够的内存来抛出OutOfMemoryError时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道每个对象都需要堆内存,堆栈上的每个原语/引用都需要堆栈内存。



当我尝试在堆上创建一个对象时内存不足,JVM创建了一个 java.lang.OutOfMemoryError 在堆上并将它抛给我。



所以隐含地,这意味着JVM在启动时保留了一些内存。



当这个保留的内存用完时会发生什么(它肯定会被用完,下面会再讨论)并且JVM上没有足够的内存来创建java.lang.OutOfMemoryError



<它只是挂起来吗?或者他会给我一个 null ,因为没有内存到 new 一个OOM实例?

  try {
Object o = new Object();
//和需要内存的操作(好吧......就像所有东西一样)
} catch(java.lang.OutOfMemoryError e){
// JVM没有足够的内存来创建java实例.lang.OutOfMemoryError向我们抛出
//下一步是什么?挂在这里,永远陷入困境?
//或机器会决定给我们一个空吗? (因为它没有内存给我们提供比null更有用的东西)
e.printStackTrace(); // e.printStackTrace()也需要内存.. = X
}

==



为什么JVM无法保留足够的内存?



无论如何如果JVM没有办法回收那个内存,那么内存仍然可以被用尽:

  try {
Object o = new Object();
} catch(java.lang.OutOfMemoryError e){
// JVM有100个单位的备用内存。 1用于创建此OOM。
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e2){
// JVM有99个单位的备用内存。 1用于创建此OOM。
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e3){
// JVM有98个单位的备用内存。 1用于创建此OOM。
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e4){
// JVM有97个单位的备用内存。 1用于创建此OOM。
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e5){
// JVM有96个单位的备用内存。 1用于创建此OOM。
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e6){
// JVM有95个单位的备用内存。 1用于创建此OOM。
e.printStackTrace();
//这个JVM不能有无限的保留内存,他最终会耗尽
}
}
}
}
}
}

或更简洁:

  private void OnOOM(java.lang.OutOfMemoryError e){
try {
e.printStackTrace();
} catch(java.lang.OutOfMemoryError e2){
OnOOM(e2);
}
}


解决方案

JVM从未真正耗尽内存。它预先对堆栈进行内存计算。



JVM的结构,第3章,第3.5.2节说明:



  • 如果可以动态扩展Java虚拟机堆栈,并且尝试进行扩展但可以使用足够的内存
    来实现扩展,或者如果内存不足则可以生成
    可用于为新的
    线程创建初始Java虚拟机堆栈,Java虚拟机抛出 OutOfMemoryError


,第3.5.3节。



< blockquote>

  • 如果计算需要的堆量超过自动存储管理系统可用的堆,则Java虚拟机
    将抛出 OutOfMemoryError




因此,它在分配对象之前提前计算。






JVM尝试为内存中的对象分配内存,称为永久生成区域(或PermSpace)。如果分配失败(即使在JVM调用垃圾收集器尝试和分配可用空间之后),它也会抛出 OutOfMemoryError 。即使异常也需要内存空间,因此错误将无限期抛出。



进一步阅读。?此外, OutOfMemoryError 可能出现在不同的 JVM结构中。


I am aware that every object requires heap memory and every primitive/reference on the stack requires stack memory.

When I attempt to create an object on the heap and there's insufficient memory to do so, the JVM creates an java.lang.OutOfMemoryError on the heap and throws it to me.

So implicitly, this means that there is some memory reserved by the JVM on startup.

What happens when this reserved memory is used up (it would definitely be used up, read discussion below) and the JVM does not have enough memory on the heap to create an instance of java.lang.OutOfMemoryError?

Does it just hang? Or would he throw me a null since there's no memory to new an instance of OOM ?

try {
    Object o = new Object();
    // and operations which require memory (well.. that's like everything)
} catch (java.lang.OutOfMemoryError e) {
    // JVM had insufficient memory to create an instance of java.lang.OutOfMemoryError to throw to us
    // what next? hangs here, stuck forever?
    // or would the machine decide to throw us a "null" ? (since it doesn't have memory to throw us anything more useful than a null)
    e.printStackTrace(); // e.printStackTrace() requires memory too.. =X
}

==

Why couldn't the JVM reserve sufficient memory?

No matter how much memory is reserved, it is still possible for that memory to be used up if the JVM does not have a way to "reclaim" that memory:

try {
    Object o = new Object();
} catch (java.lang.OutOfMemoryError e) {
    // JVM had 100 units of "spare memory". 1 is used to create this OOM.
    try {
        e.printStackTrace();
    } catch (java.lang.OutOfMemoryError e2) {
        // JVM had 99 units of "spare memory". 1 is used to create this OOM.
        try {
            e.printStackTrace();
        } catch (java.lang.OutOfMemoryError e3) {
            // JVM had 98 units of "spare memory". 1 is used to create this OOM.
            try {
                e.printStackTrace();
            } catch (java.lang.OutOfMemoryError e4) {
                // JVM had 97 units of "spare memory". 1 is used to create this OOM.
                try {
                    e.printStackTrace();
                } catch (java.lang.OutOfMemoryError e5) {
                    // JVM had 96 units of "spare memory". 1 is used to create this OOM.
                    try {
                        e.printStackTrace();
                    } catch (java.lang.OutOfMemoryError e6) {
                        // JVM had 95 units of "spare memory". 1 is used to create this OOM.
                        e.printStackTrace();
                        //........the JVM can't have infinite reserved memory, he's going to run out in the end
                    }
                }
            }
        }
    }
}

Or more concisely:

private void OnOOM(java.lang.OutOfMemoryError e) {
    try {
        e.printStackTrace();
    } catch (java.lang.OutOfMemoryError e2) {
        OnOOM(e2);
    }
}

解决方案

The JVM never really runs out of memory. It does memory computation of the heap stack in advance.

The Structure of the JVM, Chapter 3, section 3.5.2 states:

  • If Java virtual machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java virtual machine stack for a new thread, the Java virtual machine throws an OutOfMemoryError.

For Heap, Section 3.5.3.

  • If a computation requires more heap than can be made available by the automatic storage management system, the Java virtual machine throws an OutOfMemoryError.

So, it does a computation in advance before doing allocation of the object.


What happens is that the JVM tries to allocate memory for an object in the memory called Permanent Generation region (or PermSpace). If allocation fails (even after the JVM invokes the Garbage Collector to try & allocate free space), it throws an OutOfMemoryError. Even exceptions requires a memory space so the error will be thrown indefinitely.

Further reading.? Furthermore, OutOfMemoryError can occur in different JVM structure.

这篇关于当没有足够的内存来抛出OutOfMemoryError时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆