检测内存不足错误

我想为我的系统提供一种检测内存不足异常是否发生的方法。本练习的目的是通过 JMX 公开此标志并采取相应的操作(例如,通过在监视系统上配置相关警报),否则这些错误会持续数天而不被注意到。

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

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

我看到的一种可能的情况是字节码操作(例如,在 )上附加某种方面,但是我不确定这是否是正确的方法,或者这通常是否可行。OutOfMemoryError

我们已经启用了,但我不认为这是这个问题的解决方案,因为它是为其他东西设计的 - 并且当这种情况发生时,它不提供Java回调。-XX:+HeapDumpOnOutOfMemoryError

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


答案 1

您可以使用内存不足警告系统;这个超出记忆的错误警告系统可以是一个灵感。您可以配置一个侦听器,该侦听器在超过某个内存阈值(例如80%)后调用 - 您可以使用此调用开始采取纠正措施。

我们使用类似的东西,当组件的内存阈值达到80%时,我们暂停组件的服务,然后启动清理操作;仅当使用的内存低于另一个可配置值阈值时,组件才会返回。


答案 2

有一篇文章基于Scorpion已经给出了链接的帖子

该技术再次基于使用MemoryPoolMXBean并订阅“超出内存阈值”事件,但它与原始帖子中描述的略有不同。

作者指出,当您订阅普通的“超出内存阈值”事件时,存在“误报”的可能性。想象一下,当内存消耗超过阈值时,将很快执行垃圾回收,并且在此之后释放大量内存。事实上,这种情况在实际应用中很常见。

幸运的是,还有另一个阈值,“收集使用阈值”和相应的事件,该事件在垃圾回收后立即根据内存消耗触发。当您收到该事件时,您可以更加确信您的内存不足。


推荐