为了账号安全,请及时绑定邮箱和手机立即绑定

JVM是否可以从OutOfMemoryError中恢复而无需重新启动

JVM是否可以从OutOfMemoryError中恢复而无需重新启动

万千封印 2019-10-31 14:11:13
如果JVM有机会在更多对象分配请求出现之前运行GC,那么JVM是否可以从OutOfMemoryError中恢复而无需重新启动?各种JVM实现在这方面是否有所不同?我的问题是关于JVM恢复,而不是用户程序通过捕获错误来尝试恢复。换句话说,如果将OOME抛出到应用程序服务器(jboss / websphere / ..)中,我是否必须重新启动它?或者,如果其他请求似乎没有问题,我可以让它运行。
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

它可能有效,但是通常是一个坏主意。无法保证您的应用程序将成功恢复,或者无法知道它是否成功。例如:


即使采取恢复步骤(例如释放保留的内存块)后,实际上可能没有足够的内存来执行请求的任务。在这种情况下,您的应用程序可能陷入一个循环,在该循环中,它似乎反复出现恢复,然后再次耗尽内存。


OOME可以在任何线程上抛出。如果应用程序线程或库未设计为应对该问题,则可能会使某些长期存在的数据结构处于不完整或不一致的状态。


如果线程由于OOME而死,则作为OOME恢复的一部分,应用程序可能需要重新启动它们。至少,这会使应用程序更加复杂。


假设一个线程使用通知/等待或更高级别的机制与其他线程同步。如果该线程从OOME中消失,则可能会留下其他线程来等待通知(etc),这些通知永远不会出现...例如。为此进行设计可能会使应用程序更加复杂。


总而言之,设计,实施和测试要从OOME中恢复的应用程序可能会很困难,尤其是在应用程序(或其运行所在的框架或所使用的任何库)是多线程的情况下。将OOME视为致命错误是一个更好的主意。


另请参阅我对相关问题的回答:


编辑 -针对此后续问题:


换句话说,如果将OOME抛出到应用程序服务器(jboss / websphere / ..)中,我是否必须重新启动它?


不,你不必须重新启动。但这可能是明智的选择,尤其是如果您没有良好/自动的方法来检查服务是否正常运行时。


JVM将恢复正常。但是,应用程序服务器和应用程序本身可能会恢复,也可能无法恢复,这取决于它们为应对这种情况而设计的程度。(我的经验是,某些应用程序服务器并非旨在解决此问题,并且设计和实施复杂的应用程序以从OOME中恢复非常困难,而正确地对其进行测试则更加困难。)


编辑2


针对此评论:


“其他线程可能会等待通知(等)永远不会到来”真的吗?被杀死的线程是否不会解开其堆栈,随即释放资源,包括持有的锁?


对真的!考虑一下:


线程#1运行此命令:


    synchronized(lock) {

         while (!someCondition) {

             lock.wait();

         }

    }

    // ...

线程#2运行此命令:


    synchronized(lock) {

         // do stuff

         lock.notify();

    }

如果线程#1正在等待通知,并且线程#2在该// do something节中获得OOME ,则线程#2将不会进行notify()调用,线程#1可能会永远卡住,等待永远不会发生的通知。当然,保证线程#2释放lock对象上的互斥体...但这还不够!


如果不是,线程运行的代码不是异常安全的,这是一个更普遍的问题。


我听说过“异常安全”这个词(尽管我知道您的意思)。Java程序通常没有设计为可应对意外异常。确实,在上述情况下,使应用程序异常安全可能很困难,甚至不可能。


您需要某种机制将线程#1的故障(由于OOME)变成对线程#2的线程间通信失败通知。Erlang可以做到这一点……但是Java却没有。他们之所以能够在Erlang中做到这一点,是因为Erlang进程使用严格的类似于CSP的原语进行通信。即没有共享的数据结构!



查看完整回答
反对 回复 2019-10-31
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

我会说这部分取决于导致OutOfMemoryError的原因。如果JVM的内存确实不足,最好重新启动它,并在可能的情况下使用更多的内存(或效率更高的应用程序)。但是,我已经看到大量OOME是由分配2GB数组等引起的。在那种情况下,如果它像是J2EE Web应用程序,则错误的影响应该限制在该特定应用程序上,并且在JVM范围内重新启动不会有任何好处。


查看完整回答
反对 回复 2019-10-31
  • 3 回答
  • 0 关注
  • 964 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信