现在公司有个应用的生产环境发生了perm溢出问题,大家看下我思路有啥问题没
fxl545826
2013-10-26
公司有个应用是做批处理的话,我看客户的运维给发送的日志中在发生宕机的时候给的日志,有以下信息:
Heap PSYoungGen total 1322112K, used 61312K [9fffffff0a6b0000, 9fffffff5fc00000, 9fffffff5fc00000) eden space 1248960K, 0% used [9fffffff0a6b0000,9fffffff0a6b0000,9fffffff56a60000) from space 73152K, 83% used [9fffffff5b490000,9fffffff5f070000,9fffffff5fc00000) to space 74560K, 0% used [9fffffff56a60000,9fffffff56a60000,9fffffff5b330000) PSOldGen total 2501696K, used 1632367K [9ffffffe5fc00000, 9ffffffef8710000, 9fffffff0a6b0000) object space 2501696K, 65% used [9ffffffe5fc00000,9ffffffec361be58,9ffffffef8710000) PSPermGen total 1048576K, used 1048575K [9ffffffe1fc00000, 9ffffffe5fc00000, 9ffffffe5fc00000) object space 1048576K, 99% used [9ffffffe1fc00000,9ffffffe5fbfff40,9ffffffe5fc00000) 我看意思应该是Perm区在GC之后依然空间不够所以OOM,那么这个weblogic下面只是跑了一个应用,一个应用能到1024M的perm应该不太能想象,在测试环境模拟同样的功能256M都没问题,可能有一些东西还是模拟不了。猜测可能生产环境内存配置的不太合理,例如把JVM内存配置都超过了本身物理内存,或者应用的确有perm的内存泄漏问题,否则不太可能到1024,但是在测试没模拟出来。 但是我需要什么样的数据来验证我的这些猜想呢,我只是抓了heap的dump分析了半天好似没什么进展,几乎没法区分哪些是在perm区分配的对象。求指导思路啊 |
|
RednaxelaFX
2013-10-26
请问是有hs_err<pid>.log形式的文件名的crash log,还是只是OOM异常然后触发Weblogic自己的错误处理?
PermGen爆有两种可能最大,一直是不断加载新类,一种是不断intern新内容的字符串。要知道是哪种情况得先回答我前面的问题,再找具体检查的办法。 |
|
fxl545826
2013-10-26
是hs_err<pid>.log形式的文件名的log,intern的地方估计可能不大。
每次我jmap,出来的第一行都是写了基本占用60M左右还是很稳定的,看自己的应用代码里面我搜索没人用intern的方法。 不断的加载类我用jvisualvm监控测试的时候的确类的数量在执行任务的时候会看到加载类的数量会一会就提高1000个加载类这样,当perm满的时候还是可以卸载掉的,如果确定可能是这个问题,我需要用dump的那个堆文件来分析定位问题么? |
|
fxl545826
2013-10-26
对了,还有就是这个功能使用了 drools 的规则引擎,这个 drools 有自己的类加载器,那么在运算的时候会使用这个,可能会导致。
那个class loading这个日志信息应该是也可以打印的吧?我看 Java Performance里面说到过,但是看这个章节的时候大部分都是提供了可视化的监控方式,我这边生产环境无法连接,企业用户比较悲剧,不给权限监控,但是可以提供参数加日志信息,是不是有这样一个参数我来看到每次gc的类加载和卸载的数量,回收前大小/回收后大小等信息的?如果有这个我觉得可以断定是否有这个问题 |
|
RednaxelaFX
2013-10-26
如果有crash log请把完整的crash log发出来看看(那个hs_err文件)
|
|
fxl545826
2013-10-27
我创建了一个gist,https://gist.github.com/ethanfu/7178680
|
|
RednaxelaFX
2013-10-27
呃啊,果然是VM crash了。但这是HP自己维护的HP-UX/Itanium版JDK6,代码跟Oracle/Sun的JDK6不完全对应得上,所以我的经验不一定能直接对应得上。
现在的状况是VM没分配到足够native memory而选择直接crash掉,所以原本我想建议的-XX:OnOutOfMemoryError="..."行不通,这种crash不会走这个报错路径。 有另外一个办法是用持续监控。在外部写个脚本,定时调用: jmap -permstat <pid> 得到的结果会告诉你PermGen里有多少空间是被intern string吃掉的,而其它空间包含哪些已加载的类。多次对比打印出来的日志就可以看出什么东西有泄漏了。 不过要小心的是PermGen比较大的时候跑这个命令可能会有一定停顿时间,像是1秒左右的。 |
|
fxl545826
2013-10-27
嗯,我在测试环境尝试用你说的这个命令了,然后我看到intern的数量倒是还算可以,最多的时候好似在60M左右。
不过我可以写个脚本在生产环境试试,就是定期jmap拿文件对比下,如果客户因为jmap会导致不响应不忍受,我就检测到一些条件触发的好。我在测试环境256M的情况下好似都5s左右似的,挺奇怪的。 还有jmap之后的文件有文档来解释下吧?能给点资料么?我现在大部分知识都是通过看你推荐的那本 Java Performance 来的 |
|
fxl545826
2013-10-27
还有就是如果这个配置人员把环境配置的有问题,例如把给JVM的heap+unheap大于本机内存是不是也会这样,本该gc的时候是不是软件以为有内存但是分配不到就OOM?
|
|
RednaxelaFX
2013-10-27
我忘了说,jmap -permstat也可以对core dump file起作用的。如果你之前除了看到有hs_err<pid>.log形式的crash log,还有core dump文件的话,请试试用这个命令去查看它的状况:
jmap -permstat <path/to/java> <path/to/core/dump> 例如, jmap -permstat /opt/java6/bin/IA64W/java /tmp/core.1234 之类的。记得要在实际crash的那个机器上直接执行,免得遇到RPWT... 要是没留下core dump的话下次crash的时候一定要想办法留下来,别删了。 fxl545826 写道 还有就是如果这个配置人员把环境配置的有问题,例如把给JVM的heap+unheap大于本机内存是不是也会这样,本该gc的时候是不是软件以为有内存但是分配不到就OOM?
这是一种可能。但我不太清楚HP版有没有啥特别诡异的地方,所以我就不多评论了⋯ |
相关讨论
相关资源推荐
- hibernate_配置cascade_及all-delete-orphan.doc
- A collection with cascade=“all-delete-orphan“ was no longer referenced by the owning entity instance
- HibernateException - A collection with cascade="all-delete-orphan" was no longer referenced by the
- org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer refere...
- JPA级联操作报JpaSystemException cascade=“all-delete-orphan“问题的处理
- hibernate cascade属性 all-delete-orphan
- 在进行jpa更新操作中报异常Cascade="All-Delete-Orphan" 处理
- hibernate-级联cascade="all-delete-orphan"
- spring data jpa 保存报错记录A collection with cascade=\"all-delete-orphan\" was no longer referenced by th...
- cascade="all-delete-orphan" 处理