如何调试JBoss或PostgreSQL内存不足的问题?

时间:2011-01-03 20:44:11

标签: java java-ee jboss

3 个答案:

答案 0 :(得分:2)

在使用这个基本过程之前,我已经解决了这些类型的问题:

  1. 在启动JVM时设置JVM选项-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps
  2. 运行应用程序,等待失败(如果可以,则导致失败),收集转储(.hprof文件)
  3. Eclipse Memory Analyzer (MAT)中查看转储,其中有一个很好的“泄漏嫌疑人报告”
  4. 报告有希望说“类XYZ的82,302个实例占据堆空间的74%”。如果需要更多信息,可以检查其中一些对象。
  5. 希望这足以至少指出你正确的方向找到你的泄漏。

    快乐的调试!

答案 1 :(得分:1)

这不足以作为诊断信息。

但是,让我们从我们拥有的东西开始吧。我不知道你用什么来显示内存统计信息,但它表明你的整体系统内存消耗已经增加了15 GB。这很奇怪,考虑到你只给了JBoss 6 GB的堆。

所以要做的第一件事是验证JBoss是否是实际问题。最简单的方法是使用top,按总虚拟内存(VIRT)或驻留集大小(RES)进行排序。要更改排序字段,请键入大写“F”,然后在随后的屏幕中选择该字段。

如果是JBoss进程占用了所有内存,那么你需要弄清楚它的发展方向。可能性包括大内存映射JAR文件,通过Java分配的堆外缓冲区和从本机模块分配的内存。由于您将从顶部获得进程ID,因此使用pmap生成进程地址空间列表并查找大块(特别是名为[anon]的大块)。

如果不清楚内存的分配位置,您可以随时向进程发送SIGQUITkill -QUIT),该进程会将一个线程转储写入stderr(它将转到控制台)或者 - 希望 - 到日志文件)。连续几次这样做,并寻找常见的堆栈跟踪。


根据您的更新,显示JBoss进程的虚拟大小增长,我认为检查Java堆是浪费时间。虽然我认为JVM可能忽略了-Xmx选项,但这种可能性极小。

这意味着增长发生在非堆内存中。一些可能性:

  • 使用直接ByteBuffer s。如果您使用缓冲区来缓存数据库中的结果,那么您很可能分配了太多缓冲区。这将通过pmap进行诊断,查找大型[anon]块。
  • 不受控制的线程创建。每个线程都需要一些空间用于其线程堆栈。我不希望这是问题,因为每线程空间的数量很小(iirc,低于1 MB);你必须创造成千上万的人。您可以使用pmap进行诊断,查找小[anon]块,或将SIGQUIT发送到JVM。
  • 在C堆上分配大量内存的本机代码。您可以使用pmap进行诊断,但第一步是检查您的依赖项以查看是否存在本机库。如果有,请使用gdb或同等版本进行调试。

作为最后的评论:我建议只是尝试选项,看看哪些有效,哪些不起作用,而不是询问在低内存条件下可能会有什么作用。

答案 2 :(得分:0)

一种解决方案是使用VisualVM将远程JMX用于JBoss服务器(包含在最新的JDK中)。