我正在尝试调试内存中的JBoss问题。当JBoss启动并运行一段时间时,它似乎按照启动配置的意图使用内存。但是,当使用唯一的web应用程序JBoss进行一些未知的用户操作(或者日志文件增长到一定大小)时,内存会急剧增加,JBoss会冻结。当JBoss冻结时,由于内存不足,很难终止进程或做任何事情。
当进程最终通过a-9参数终止并且服务器被重新启动时,日志文件非常小,只包含来自新启动进程的输出,而不包含任何关于为什么内存增加了这么多的信息。这就是为什么调试如此困难的原因: server.log没有来自终止进程的信息。日志被设置为2GB,新进程的日志文件只有大约300 Kb,尽管它在正常内存环境下增长正常。
这是关于JBoss配置的信息:
JBoss (MX MicroKernel) 4.0.3
JDK 1.6.0更新22
PermSize=512m
MaxPermSize=512m
Xms=1024m
Xmx=6144m
这是系统的基本信息:
操作系统: CentOS Linux5.5
内核和CPU: Linux2.6.18-194.26.1.el5在x86_64上
处理器信息: Intel(R) Xeon(R) CPU E5420 @ 2.50GHz,8个核心
这是jboss服务启动几分钟后正常预冻结状态下系统的良好示例信息:
正在运行的进程: 183
CPU平均负荷: 0.16 (1分钟) 0.06 (5分钟) 0.09 (15分钟)
CPU使用率: 0%用户,0%内核,1% IO,99%空闲
实际内存:17.38GB,2.46GB
虚拟内存: 19.59 GB总计,使用0字节
本地磁盘空间:总计113.37 GB,使用11.89GB
当JBoss冻结时,系统信息如下所示:
正在运行的进程: 225
CPU平均负载: 4.66 (1分钟) 1.84 (5分钟) 0.93 (15分钟)
CPU使用率: 0%用户,12%内核,73% IO,15%空闲
实际内存:17.38GB总容量,17.18GB使用
虚拟内存:19.59GB总容量,706.29 MB
本地磁盘空间:总计113.37 GB,使用11.89GB
===========================================================
此问题的更新如下所示
非常感谢您的评论。我们正在发布对这个问题的更新,这可能会有帮助。
在再出现3次内存问题时,使用unix实用程序似乎表明JBoss进程是消耗所有内存的进程。当问题发生时,它似乎很快就会发生。例如,在JBoss之后的一段时间内运行良好(例如。(几天),用户在某一时刻采取了一些神秘的行动,之后,内存消耗似乎需要1-3分钟才能上升到导致性能严重下降的水平,再过5-10分钟,这种退化就会变得严重(例如。很难通过ssh运行简单的bash命令)。当然,这种模式会因用户在web应用程序上所做的事情而有所不同。
例如,在按内存进行排序时,据报告JBoss进程有以下统计数据(请注意,实际内存为17.38GB,JBoss仅为6GB堆):
VIRT (总虚拟内存):23.1g
驻地设置尺寸: 15g
%CPU: 111.3%
MEM%:97.6%
在同一示例中,9分钟后,据报告JBoss流程具有以下统计信息:
VIRT (总虚拟内存):39.1g
驻地设置尺寸: 17g
%CPU: 415.6%
MEM%:98.4%
在使用SIGKILL信号(-9)终止JBoss进程之后,据报告,新的JBoss进程具有类似于以下统计信息的统计信息:
虚拟内存总数:7147 M
驻地设置大小: 1.3g
CPU百分比: 11.6%
MEM%:7.3%
现在我们知道是JBoss进程消耗了所有的内存,我们想知道它的去向。我们尝试过使用jmap命令,例如jmap -dump:file=/home/dump.txt 16054,但是这似乎会大大降低服务器的响应能力,在一段时间后似乎什么也不会发生(例如。提示符不返回)。我们猜测是因为可用内存太少,堆太大了,有些东西挂起了。
此外,我们在启动JVM时设置了JVM选项-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps,但是当内存问题发生时,似乎不会将任何东西写入路径。
还提出了这些其他备选办法:
使用pmap生成进程地址空间的列表,并查找大块(特别是具有名称anon的大块)。
2连续几次将SIGQUIT (杀死-QUIT)发送到进程,并查找常见的堆栈跟踪
3使用j堆栈获得一个线程转储,命令包括j堆栈> tdump.out。
4混乱地处理JBoss管理工具/控制台,这些工具和控制台都包含在JBoss中,并查看当东西开始消耗内存时,会留下什么样的对象。
5探索Nagios作为另一种监视解决方案
以下是一些后续问题:
*根据上述报告的资料,对这个问题是否有新的见解或想法?
*对于上述选项1-5,在问题所造成的极低内存环境下,哪一个最有可能工作?
*对于上述备选方案1-5,它们最有可能在问题允许诊断的非常短的时间框架内工作(例如。1-3分钟)?
*当某个特定进程的内存使用达到几个特定百分比阈值时,是否有一种方法可以自动地将时间戳写入文本文件,以便在查看JBoss日志文件时可以使用此时间戳?
*是否有办法在某一特定进程的内存使用达到几个特定百分比阈值时,自动发送带有时间戳的电子邮件,以便我们能够开始更有针对性的监测?
发布于 2011-01-03 21:46:08
我曾经用这个基本过程解决过这些类型的问题:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dumps。希望这至少能给你指明正确的方向,找到你的漏洞。
调试愉快!
发布于 2011-01-03 22:09:16
这还不足以进行诊断。
但让我们从我们所拥有的开始吧。我不知道您正在使用什么来显示内存统计数据,但它显示您的系统内存消耗总量已经跃升了15 GB。这很奇怪,因为您只为JBoss提供了一个6 GB的堆。
因此,首先要做的是验证JBoss是实际问题。最简单的方法是使用top,按总虚拟内存(VIRT)或驻留集大小(RES)对其进行排序。若要更改排序字段,请键入大写"F“,然后在后面的屏幕中选择该字段。
如果是JBoss进程消耗了所有的内存,那么您就需要弄清楚它的去向。可能的情况包括:大内存映射的JARfiles、通过Java分配的堆外缓冲区和从本机模块分配的内存。由于您将从顶部获得进程ID,所以使用pmap生成进程地址空间的列表,并查找大块(特别是名为[anon]的大块)。
如果不清楚在何处分配内存,则始终可以向进程发送SIGQUIT (kill -QUIT),该进程将向stderr写入线程转储(这将转到控制台,或者--希望--到日志文件)。连续多次执行此操作,并查找常见的堆栈跟踪。
根据您的更新(显示JBoss进程的虚拟大小),我认为检查Java堆是浪费时间。虽然我认为JVM可能忽略了-Xmx选项,但这是极不可能的。
这意味着增长发生在非堆内存中。一些可能性:
ByteBuffer。如果您使用缓冲区来缓存数据库的结果,那么很可能您分配了太多的缓冲区。这将通过pmap诊断,寻找大型[anon]块。pmap、查找小型[anon]块或向JVM发送SIGQUIT来诊断这一点。pmap进行诊断,但第一步是检查依赖项,以确定是否存在本机库。如果存在,请使用gdb或等效的方法进行调试。作为最后的评论:与其问什么在低内存条件下可能起作用,我建议只是尝试这些选项,看看什么起作用和什么不起作用。
发布于 2011-01-03 20:50:17
一种解决方案是在JBoss服务器上使用VisualVM (包括在最新的JDK中)的远程JMX。
https://stackoverflow.com/questions/4588202
复制相似问题