检测内存不足错误

min*_*das 14 java exception-handling exception out-of-memory

我想为我的系统提供一种检测是否发生了内存不足异常的方法.此练习的目的是通过JMX公开此标志并相应地采取行动(例如,通过在监控系统上配置相关警报),否则这些错误将被忽视几天.

对此的简单方法是为每个线程设置一个未捕获的异常处理程序,并检查引发的异常是否为实例OutOfMemoryError并设置相关标志.但是,由于以下原因,这种方法不现实:

  • 异常可能发生在任何地方,包括第三方库.我无能为力阻止他们抓住Throwable并保留自己.
  • 库可以生成自己的线程,我无法为这些线程强制执行未捕获的异常处理程序.

我看到的一个可能的场景是字节码操作(例如,附加某种方面OutOfMemoryError),但是我不确定这是否是正确的方法或者这是否可行.

我们-XX:+HeapDumpOnOutOfMemoryError启用了,但是我没有将此视为此问题的解决方案,因为它是为其他内容设计的 - 并且在发生这种情况时它不提供Java回调.

有没有人这样做过?你会如何解决它或建议解决它?欢迎任何想法.

Sco*_*ion 5

您可以使用内存不足警告系统; 这个http://www.javaspecialists.eu/archive/Issue092.html可以成为一种灵感.您可以配置在某个内存阈值(例如80%)被破坏后调用的侦听器 - 您可以使用此调用开始采取纠正措施.

我们使用类似的东西,当组件的内存阈值达到80%时,我们暂停组件的服务并开始清理操作; 只有当使用的内存低于另一个可配置的值阈值时,组件才会返回.


Ami*_*ani 0

我们启用了 -XX:+HeapDumpOnOutOfMemoryError ,但我不认为这是解决此问题的方法,因为它是为其他目的而设计的 - 并且在发生这种情况时它不提供 Java 回调。

这个标志应该就是您所需要的。将生成的堆转储文件的输出目录设置在您定期检查的某个已知位置。回调对你来说没有任何用处。如果内存不足,你无法保证回调代码有足够的内存来执行!您所能做的就是收集数据并使用外部程序来分析内存不足的原因。任何在过程中进行恢复的尝试都可能会产生更大的问题。

字节码检测是可能的,但很难。 HPjmeter 的监控工具能够预测未来的 OOM(带有警告)——但仅限于基于 HP-UX/Itanium 的系统。您可以专用一个守护线程来计算进程中使用的内存,并在超出时触发警报,但实际上您并没有解决问题。