在Java中处理内存不足情况的最佳方法是什么?
我们有一个生成新JVM并代表用户执行代码的应用程序。有时,这些内存会耗尽,在这种情况下,它们的行为方式会截然不同。有时他们抛出一个OutOfMemoryError,有时他们冻结。我可以通过一个非常轻量级的后台线程来检测后者,该线程在内存不足时停止发送心跳信号。在这种情况下,我们杀死了JVM,但我们永远无法绝对确定无法接收心跳信号的真正原因是什么。(也可能是网络问题或细分故障。) 可靠地检测JVM内存不足情况的最佳方法是什么在Java中处理内存不足情况的最佳方法是什么?,java,linux,process,garbage-collection,out-of-memory,Java,Linux,Process,Garbage Collection,Out Of Memory,我们有一个生成新JVM并代表用户执行代码的应用程序。有时,这些内存会耗尽,在这种情况下,它们的行为方式会截然不同。有时他们抛出一个OutOfMemoryError,有时他们冻结。我可以通过一个非常轻量级的后台线程来检测后者,该线程在内存不足时停止发送心跳信号。在这种情况下,我们杀死了JVM,但我们永远无法绝对确定无法接收心跳信号的真正原因是什么。(也可能是网络问题或细分故障。) 可靠地检测JVM内存不足情况的最佳方法是什么 理论上,-XX:OnOutOfMemoryError选项看起来很有希望
- 理论上,-XX:OnOutOfMemoryError选项看起来很有希望,但由于以下缺陷,它实际上无法使用:
- 出于众所周知的原因(例如,你永远不知道它发生在哪里),捕捉OutOfMemoryError实际上不是一个好的选择,尽管它在很多情况下都有效
- 剩下的情况是JVM冻结并且不会抛出OutOfMemoryError。我仍然相信内存是导致这个问题的原因
编辑:我完全控制forking和forking JVM以及其中执行的代码,两者都在Linux上运行,如果有帮助,可以使用操作系统特定的实用程序。如果您可以同时控制应用程序和配置,最好的解决方案是找到抛出OutOfMemoryError的根本原因并修复它,而不是试图通过捕获错误或只是重新启动JVM来隐藏症状 从您描述的情况来看,在JVM上运行的应用程序显然是在泄漏内存,只是在使用未充分配置的资源(在您的情况下是内存)运行,或者偶尔处理需要异常大的堆块的事务。针对这些情况的解决方案将有所不同:
java .... -XX:+HeapDumpOnOutOfMemoryError "-XX:OnOutOfMemoryError=kill %p"
经过一段时间的试验,这是一个对我们有效的解决方案:
OutOfMemoryError
并立即退出,用退出代码向控制器JVM发送内存不足的信号hs_err_pidXXX.log
是否存在并包含行“内存不足错误”。(此文件由java生成,以防崩溃。)-XX:onAutofmemoryError
由于fork问题而未使用,并且-XX:+heapdumpOnAutofmemoryError
未使用,因为堆转储超出了我们的需要
解决方案当然不是有史以来编写的最优雅的代码,但它为我们完成了任务。听起来您真正感兴趣的是检测另一个进程何时出现内存不足;这是一个关键点,你的问题标题甚至没有暗示。谢谢。我试图在文章中更清楚地说明这一点,但到目前为止我还没有改变标题,因为我能想到的所有替代标题都是误导性的。特别是,我不介意我们是从JVM内部、从调用JVM获得信息,还是将其视为具有特定行为的JVM,或者仅仅将其视为一个过程。如果你不改进你的标题,许多能够回答的人甚至不太可能打开你的帖子。“如果Java VM进程内存不足,则触发警报”可能是一个更好的标题,“捕获OutOfMemoryError”-我想,您已经在使用
setDefaultUncaughtExceptionHandler
,对吗?理论上,当OOME发生时,您可以分配几兆字节并释放它们,这样错误处理程序就有更好的生存机会。只是猜测……有关捕获OutOfMemory错误的原因有问题的信息,请参阅我假设OutOfMemory没有单一原因的问题,只是运行了任意用户代码。我认为他不是在问如何修复用户的代码,这是正确的。人们提交工作流(将其视为visua