Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检测内存不足错误_Java_Exception_Exception Handling_Out Of Memory - Fatal编程技术网

Java 检测内存不足错误

Java 检测内存不足错误,java,exception,exception-handling,out-of-memory,Java,Exception,Exception Handling,Out Of Memory,我想为我的系统提供一种检测是否发生内存不足异常的方法。此练习的目的是通过JMX公开此标志,并相应地采取行动(例如,通过在监控系统上配置相关警报),否则这些错误会在数天内不被注意到 对此,最简单的方法是为每个线程设置一个,检查引发的异常是否是OutOfMemoryError的实例,并设置一个相关的标志。但是,这种方法不现实,原因如下: 异常可能发生在任何地方,包括第三方库。我无法阻止他们捕捉并保存丢弃的文件 库可以生成它们自己的线程,我没有办法为这些线程强制执行未捕获的异常处理程序 我看到的一

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

对此,最简单的方法是为每个线程设置一个,检查引发的异常是否是
OutOfMemoryError
的实例,并设置一个相关的标志。但是,这种方法不现实,原因如下:

  • 异常可能发生在任何地方,包括第三方库。我无法阻止他们捕捉并保存丢弃的
    文件
  • 库可以生成它们自己的线程,我没有办法为这些线程强制执行未捕获的异常处理程序
我看到的一种可能的情况是字节码操作(例如,在
OutOfMemoryError
上附加某种方面),但是我不确定这是否是正确的方法,或者这在一般情况下是否可行

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

有人这样做过吗?你会如何解决它或建议解决它?欢迎提出任何意见

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

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


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

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

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

您可以使用静态
线程捕获任何和所有未捕获的异常。setDefaultUncaughtExceptionHandler。
当然,如果有人捕获所有可丢弃的内容,则没有帮助。(我不认为任何事情都会发生,尽管对于OOME,我怀疑你会得到一个级联效应,直到有问题的
try
块之外的东西爆炸了。)希望线程已经释放了足够的内存,让异常处理程序能够工作;当你试图处理OOM错误时,错误确实会成倍增加。

蝎子已经给出了一个链接

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

作者指出,当您订阅普通的“内存阈值超出”事件时,可能会出现“假警报”。想象一下这样一种情况:内存消耗高于阈值,但很快就会执行垃圾收集,之后会释放大量内存。事实上,这种情况在实际应用中非常常见


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

这可能会很有用,您可以在内存不足的情况下运行脚本。谢谢Peter-我没有注意到这篇文章。遗憾的是,提供的解决方案是针对shell而非Java的:(除了生成一个进程来运行您的代码,并监控该进程是否失败之外,在Java中监控内存不足错误并不是一个好方法。您的shell脚本可以执行任何操作,包括在JVM中调用JMX。JVM尝试处理OOME的问题是,这可能会由于OOME而失败。您可以通过从以这种方式触发的程序。我已明确提到此解决方案是不合适的-我们在不同的机器上运行多个软件实例,并且所有转储都有一个共享nfs文件夹,因为它们往往相当大(4G+)。我宁愿知道没有合适的解决方案,也不愿投入时间构建一些残废的东西。为什么要为所有转储使用一个NFS点?听起来你需要重新考虑你的设置。告诉我,什么是合适的解决方案?如果你刚刚用完内存,你能做些什么?如果你认为这样的设置不好,那将是错误的很高兴您能解释原因。但我还是要解释我的观点。我们不希望虚假内存转储溢出其他业务关键分区并中断业务流。这与为什么在Unix中需要将/var/log与/home分开的论点基本相同。除此之外,我们还运行了数十台虚拟机和maintaini使用单个装载点比在多个服务器之间查找文件方便得多。