Integer[][] data = new Integer[1000000][100000];作为上面简单的演示代码,我尝试在pandora容器中应用非凡的大内存并触发OOM (这是阿里巴巴开发的一个网络容器,就像tomcat一样)。但是这个错误似乎只影响到当前的请求,web服务不会被折叠;正如我所知,与异常不同,java中的错误不应该恢复,并且影响整个过程。我很困惑,请advice..thanks。
发布于 2022-07-05 08:10:38
首先,这是:
正如我所知,
与异常不同,java中的错误不应该恢复,并影响整个过程。
一般来说,这是事实。在web容器的情况下,在请求线程上从OOME恢复比典型的多线程应用程序更有可能成功。
为什么?
因为在一个工作线程上处理一个web请求所做的工作通常独立于其他线程。这意味着请求中的OOME不太可能使共享数据结构处于不一致的状态。
但你仍然有一个问题,那就是OOME的根本原因可能是内存泄漏.当web容器清理请求线程并创建一个新线程时,这种情况很可能不会消失。因此,对于一个网络容器来说,从OOME中恢复还是值得怀疑的。
但无论如何,这是相当普遍的行为。我认为理由是,试图以一个合理的机会成功比失败快。
那么,为什么有可能恢复呢?
考虑一下这个片段:
public void test() {
try {
Integer[][] data = new Integer[1000000][100000];
} catch (OutOfMemoryError ex) {
// log it
}
// do something else
}意见:
- Attempt to allocate large object
- Find there is not enough free space
- Run a new space GC
- Try the allocation again.
- Still not enough free space
- Run a full GC
- Try the allocation again.
- Still not enough free space
- Throw OOMEnew Integer[10000][10000]是一件无所不包的事情。如果它触发了一个OOME,那么到目前为止它分配的对象都是不可访问的。因此,如果// do something else代码试图分配另一个对象,而堆仍然满,那么JVM将再次运行GC .会回收那些无法到达的物体..。我们又开始做生意了。--data超出范围时,它所引用的Integer[][]和Integer[]对象树现在可能会被GC.检测到。
如果在子线程上抛出OOME,并且允许线程死亡,则
关键是,在从OOME中捕获和恢复的时候,可能会有一些可收集的垃圾。
那么,如果有可能恢复,为什么人们建议反对从海洋生态系统中恢复呢?
时,您的代码正在更新它。
notify。如果B获得OOME,它可能会完全死掉,或者它可能试图恢复.当它的锁被释放的时候。无论哪种方式,线程A都有可能永远被卡在一起,等待永远不会发生的通知。(线程B可能会触发应用程序关闭以避免这种情况。)发布于 2022-07-05 07:05:36
错误OutOfMemoryError: Java heap space类似于任何其他异常,它只会导致当前线程终止。这只是关于耗尽Java堆空间的问题。因此,如果线程被杀死,并且该线程中创建的所有对象都无法访问并可能被收集,那么就有足够的堆空间继续运行,并且整个应用程序没有理由崩溃。
只有当应用程序超出操作系统所能提供的内存时,应用程序本身才会被操作系统杀死。但是,您可以在一些JVM中使用一些键显式地崩溃任何内存不足的错误,例如-XX:+CrashOnOutOfMemoryError。
https://stackoverflow.com/questions/72865015
复制相似问题