9

我有一个在 Websphere Application Server 6.0 上运行的应用程序,由于内存不足,它几乎每天都会崩溃。从详细的 GC 可以确定存在内存泄漏(其中很多)

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

现在我正在寻找一些方法来自动化它。根本问题是如何检测 OOM 状况。一种方法是创建将定期搜索新堆转储的 shell 脚本。这种方法让我觉得有点脏。另一种方法可能是以某种方式利用 JMX。但我在这方面的经验很少或根本没有,也不知道如何去做。

还是在 WAS 中为此提供了某种触发器/挂钩?非常感谢您的每一个建议!

4

9 回答 9

10

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

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=<value>
于 2009-08-25T08:47:45.377 回答
5

如果您希望自动进行堆转储,我会看到两个选项,但@Mark 在 OOM 上使用堆转储的解决方案并不令人满意。

  1. 您可以使用MemoryMXBean来检测高内存压力,然后如果使用(或使用增量)看起来很高, 则以编程方式创建堆转储。
    • 您可以使用 cron'd shell 脚本定期获取内存使用信息并生成堆转储jmap(本地和远程都可以使用)。

如果您可以在 OOM 上进行回调,那就太好了,但是,嗯,该回调可能会因 OOM 错误而崩溃。:)

于 2009-08-25T09:45:22.250 回答
4

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

看看上面链接的检测内存不足部分。

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

于 2009-08-25T09:37:01.220 回答
2

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

也许甚至 websphere 可以为您做到这一点!?

于 2009-08-25T08:50:31.300 回答
1

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

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

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

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

于 2009-08-25T09:05:35.560 回答
1

从监控的角度来看,我们在 ITCAM 方面的经验并不出色。我们放弃了它,转而支持 CA Wily Introscope。

于 2009-08-25T15:38:27.837 回答
0

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

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

于 2009-08-25T11:31:37.480 回答
0

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

正如已经观察到的那样,存在用于分析这些问题的各种工具。我在 ITCAM for WebSphere 上取得了成功,作为一名 IBM 员工,我可以随时访问它。我们很快就能够在出现问题的情况下识别出确切的代码行。

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

于 2009-08-25T15:20:24.863 回答
0

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

于 2010-12-22T20:39:02.197 回答