Java 如何检测内存不足情况?

Java 如何检测内存不足情况?,java,memory-leaks,websphere,out-of-memory,Java,Memory Leaks,Websphere,Out Of Memory,我有一个运行在WebSphereApplicationServer6.0上的应用程序,它几乎每天都会因为内存不足而崩溃。从verbose GC可以确定存在内存泄漏(其中很多) 不幸的是,该应用程序是由外部供应商提供的,而修复这些问题是一个缓慢而痛苦的过程。作为流程的一部分,我需要在每次OOM发生时收集日志和堆转储 现在我正在寻找一种方法来实现自动化。基本问题是如何检测OOM条件。一种方法是创建shell脚本,定期搜索新的heapdump。这种方法对我来说有点脏。另一种方法可能是以某种方式利用JM

我有一个运行在WebSphereApplicationServer6.0上的应用程序,它几乎每天都会因为内存不足而崩溃。从verbose GC可以确定存在内存泄漏(其中很多)

不幸的是,该应用程序是由外部供应商提供的,而修复这些问题是一个缓慢而痛苦的过程。作为流程的一部分,我需要在每次OOM发生时收集日志和堆转储

现在我正在寻找一种方法来实现自动化。基本问题是如何检测OOM条件。一种方法是创建shell脚本,定期搜索新的heapdump。这种方法对我来说有点脏。另一种方法可能是以某种方式利用JMX。但我在这方面几乎没有经验,也不知道怎么做


或者是某种触发/钩子?非常感谢你的每一个建议

您可以在启动时将以下参数传递给JVM,并在OutOfMemoryError上自动生成堆转储。第二个参数用于指定堆转储文件的路径。通过使用它,您至少可以检查特定文件的存在,以查看是否发生了堆转储

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=<value>
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=

如果您乐观地认为应用程序可以存活12小时,那么除了等待应用程序崩溃之外,还可以像每晚一样编写一个可控重启脚本

也许甚至websphere也能为您做到这一点

您可以添加一个侦听器(会话作用域或应用程序作用域属性侦听器)类,该类将在每次在会话/应用程序作用域中添加新对象时调用

在此-您可以尝试在调用运行gc时检查应用程序使用的总内存(记录它)(注意,调用它并不意味着gc将始终运行)

(以上是基于使用量增长的日志部分和gc)

对于计划gc: 此外,您还可以保留一个计时器任务类,该类每隔几小时运行一次,并执行gc请求。

您看过了吗?它使用JMX为您提供各种JVM指标的可见性,包括内存信息。首先,使用它来监视应用程序可能是值得的,以了解内存是如何/何时消耗的。您可能会发现内存在一天中被均匀地消耗,或者在使用某些功能时被消耗

看看上面链接的部分


如果需要,您可以编写一个脚本来自动监视应用程序并触发所需的任何操作。JConsole将指示您需要轮询哪些JMX方法。

如果您想要自动进行堆转储,但在OOM上使用堆转储是不令人满意的,我看到两个选项

  • 您可以使用来检测高内存压力,然后检测使用率(或使用率增量)是否较高。
    • 您可以使用cron'dshell脚本定期获取内存使用情况信息并生成堆转储(在本地和远程工作)

  • 如果你能在OOM上有一个回调就好了,但是,嗯,这个回调可能会因为OOM错误而崩溃。:)

    您看过最新Java 6 JDK中的jvisualvm工具吗


    它非常适合检查正在运行的代码。

    我认为,当OOM发生时,您需要堆转储。随着时间的推移,定期收集信息应该可以了解正在发生的事情

    正如所观察到的那样,存在各种分析这些问题的工具。我已经成功地使用了itcamforwebsphere,作为一名IBMer,我已经准备好访问它。我们很快就能够在出现问题的情况下识别出准确的代码行


    如果有任何方法可以获得这种性质的工具,那么这就是方法。

    从监控角度来看,我们在ITCAM方面的经验还不够出色。我们放弃了它,取而代之的是CA-willy-Introscope。

    应该可以编写一个简单的程序,从内核获取进程列表,并扫描它以查看您的WAS进程是否仍在运行。在Unix机器上,您可能会在几分钟内(如果您知道Perl的话)用Perl编写一些东西,但不确定在Windows下会有多困难。大约每五分钟将其作为计划任务运行一次,如果进程没有出现,您可以让它退出另一个处理堆转储的进程,然后重新启动WAS。

    谢谢。我正在使用它,但是我需要某种通知,heapdump已经创建。我正在寻找比定期扫描文件系统更好的方法。我更新了我的答案,所以您只需要检查特定文件是否存在。我不确定是否有更好的方法。只需使用类似的方式来通知您:-XX:onAutofmemoryError=“echo PID%p刚刚生成了一封heapdump |邮件admin@admin.com“给您发送邮件或运行任何您想要通知您的命令。谢谢您的回答。不幸的是,如果详细GC图中存在内存泄漏(=对对象的不必要引用),那么运行GC没有任何帮助。我可以看到垃圾收集器经常在OOM之前被触发。在这种情况下,如果您知道其他未使用的活动对象,您可以将它们从作用域中删除(应用/会话)在一段确定的时间之后。好吧,这会在短期内帮助我。从另一方面来说,我需要修复泄漏。这种方法会阻止我在OOM发生时收集日志。啊,我想你只需要等到你的外部供应商解决了问题。。。当然,如果您需要报告的散列转储,那么情况就不同了:)