代码之家  ›  专栏  ›  技术社区  ›  Persimmonium

JVM:在关闭挂钩中,是否可以发现进程由于OOM而关闭?

  •  5
  • Persimmonium  · 技术社区  · 14 年前

    我在Java(1.6)中运行了一个关键的进程,带有一个已注册的关闭钩子。在某些情况下,当我遇到OOM问题(更多关于该问题的详细信息,请参阅下面的内容)时,进程突然停止,我没有得到任何日志,我的catch(throable x)没有捕获到异常。

    但关闭挂钩起作用。因此,如果有一种方法可以知道进程将因某个讨厌的OOM而关闭,那么我可以在退出之前记录必要的信息。

    有办法吗?

    关于房间 : 不知道例外是什么,因为正如我所说,它不会被捕获。我知道这是一个OOM,因为我从

    -XX:+HeapDumpOnOutOfMemoryError
    

    我得到一个堆转储文件。在其他情况下,会捕获一个异常,这是一个ava.lang.OutofMemoryError:gc开销限制已超出。但不确定情况总是这样。

    编辑:

    如果不清楚: 我不想阻止OOM的发生,因为在某些情况下,这是有正当理由的,我只是想确保它在应用程序日志文件中是清晰的。

    我的问题是 :在关闭挂钩中,是否可能发现进程因OOM而关闭?

    我要这么做 程序化 来自同一进程 .

    目前,最好的方法是查看是否存在堆转储文件java-pid-pid(进程的java-pid)和最近的日期,并推断出存在OOM。 我想我可以尝试runtime.getruntime().freemory()并报告这个问题,如果可用内存非常低,但不确定这有多可靠,也许当进程关闭时,它已经释放了很多内存,我认为上面的方法是最好的。

    7 回复  |  直到 14 年前
        1
  •  3
  •   Peter Knego    14 年前

    OOM很棘手,因为如果JVM内存不足,它可能不会运行异常处理代码,因为会抛出一个新的OOM。

    尝试设置 default uncaught exception handler . 它将捕获所有未捕获的异常。

        2
  •  2
  •   Alois Cochard    14 年前

    您可能可以运行另一个进程来监视OOE的日志文件(或者监视进程是否被终止),然后重新启动该进程。

    也许把你的应用作为unix deamon或windows服务会更合适。

    但是,用分析工具来调查内存泄漏呢?

    jvisualvm是个不错的选择

        3
  •  2
  •   kschneid    14 年前

    你可能想看看 -XX:OnOutOfMemoryError="cmd_with_pid_arg %p" 选项(命令字符串类似于 -XX:OnError )

        4
  •  1
  •   dacwe    14 年前

    使用监控工具,如 jvisualvm jconsole .

        5
  •  0
  •   Andreas Dolk    14 年前

    可以 (技术上)catch out-ofmemoryer错误,但是如果没有内存的话,不确定是否能够执行catch块中的代码。

    也许值得一试:(1)捕获OOM,(2)触发垃圾收集( System.gc() )尝试写一些东西到日志或控制台。不保证,但它不会破坏任何东西。

        6
  •  0
  •   Community holdenweb    7 年前

    你应该解决这个问题,而不是试图补偿它。

    堆转储将向您显示消耗内存最多的对象类型。您应该能够弄清楚这些对象在哪里被分配,或者为什么它们在被丢弃之后仍然存在。

    关于您接收到的具体错误,请看下面这个问题: Error java.lang.OutOfMemoryError: GC overhead limit exceeded --似乎最简单的解决方案是增加堆的大小。

        7
  •  0
  •   Eran Medan    14 年前

    同样,使用其他人或其他分析工具建议的jvisualvm(jdk 6,在bin文件夹中)是解决问题的最佳方法,而不是处理问题,但假设您将单独调查OOM原因,并尝试消除它们,我将考虑执行以下POC(另请参阅aloi)。S答案)

    运行一个Java进程来封装OOM抛出过程的调用如何?

    您可以捕获发送到被调用进程的输出流的任何结果,并查看是否存在可用于标识OOM的一致退出代码/堆栈跟踪

    我相信还有更多的方法,但在我看来,这是一个很好的、程序化的起点。