WebSphere 内存泄漏 Java虚拟机收藏.docx

上传人:b****7 文档编号:11329438 上传时间:2023-02-27 格式:DOCX 页数:21 大小:35.65KB
下载 相关 举报
WebSphere 内存泄漏 Java虚拟机收藏.docx_第1页
第1页 / 共21页
WebSphere 内存泄漏 Java虚拟机收藏.docx_第2页
第2页 / 共21页
WebSphere 内存泄漏 Java虚拟机收藏.docx_第3页
第3页 / 共21页
WebSphere 内存泄漏 Java虚拟机收藏.docx_第4页
第4页 / 共21页
WebSphere 内存泄漏 Java虚拟机收藏.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

WebSphere 内存泄漏 Java虚拟机收藏.docx

《WebSphere 内存泄漏 Java虚拟机收藏.docx》由会员分享,可在线阅读,更多相关《WebSphere 内存泄漏 Java虚拟机收藏.docx(21页珍藏版)》请在冰豆网上搜索。

WebSphere 内存泄漏 Java虚拟机收藏.docx

WebSphere内存泄漏Java虚拟机收藏

WebSphere内存泄漏Java虚拟机收藏

(2)

Java,WebSphere,机收,泄漏

直到现在,系统一直运行平稳。

先说说我接手这项工作的经历吧:

该项目大部分是06年10月就部署在客户那边了,到07年3月份,WAS宕机问题实在无法忍受,我才加入进来,前半年有另外一位同事断断续续处理,但对问题一直都无可奈何,而且项目负责人也没有引起足够的重视。

可想而知,最后付出的代价是非常惨重的。

在这近半年的时间内,服务器宕机63次。

每次宕机时,WAS的JVM会dump出一个heapdump.phd文件(heap快照),然后JVM就死掉了,当然,此时WAS也停止了响应。

一般我们的做法是重启,最后是干脆AIX每天晚上定时重启。

有时候一天还死多次。

大家见附件的截图(all-GC.png)。

这是我接手后,用IBM的分析工具得到的截图。

对截图的分析,留给后面对应的部分吧。

服务器不稳定、宕机问题,拖延到最后,客户愤怒了,公司高层也害怕了,部门还专门成立了八人攻关组。

当然了,我当时的压力也非常大,因为我是技术负责人,也就是实实在在干活、想主意的。

服务器诊断那段时间,从前到后,我们也是沿着一条线走下来,虽然最后发现很多路都走不通。

现在就按这个思路,也就是时间先后一步步叙述吧。

我想,大家如果也碰到类似应用服务器诊断,应该思路差不多。

术语说明:

IBMWebsphereApplicationServer:

WAS,WebSphere本身是一个平台,产品家族

OutOfMemoryError:

OOM,内存泄漏,内存溢出

GabageCollection:

GC,自动垃圾回收

ContentManagementSystem:

CMS,就是给新闻类门户网站编辑们用的系统

我们诊断大体上经历了以下几个阶段:

1、按Job调度线程池引起内存泄漏诊断:

因为很多次OOM是发生在某个特定时候,譬如14:

30、22:

40左右。

2、按应用程序引起内存泄漏诊断:

用JProfiler等工具探测:

因为总是发生OOM。

3、分离WAS怀疑有OOM的应用:

因为每个WAS应用太多,20来个,混一起没法定位。

4、用IBM官方heap、GC分析工具。

以及和IBM技术支持联系。

WAS、AIX参数优化。

5、隔离出WAS超级恶魔程序:

一个CMS产品。

6、WAS、AIX参数优化、设置。

我们走到第5步时,才出现效果。

计算一下,那时已经过去一个月了。

服务器宕机、系统不稳定,在这个验收的时候,客户已经忍无可忍,以致后来的每一次行动都得胆战心惊得去做。

一、按Job调度线程池导致内存泄漏诊断

因为从我们WAS的日志(默认是native_stderr.log)来看,最近半年的宕机时间都有一个明显时间规律。

见附件截图Job1-1.png。

我想,做过Java服务器性能调优的朋友,都知道在Web容器里面启线程池是个不太好的做法,因为Web容器本身有一个线程池,譬如Servlet线程池(Tomcat默认起25个),而自启的线程池很容易导致Servlet线程管理混乱,最终导致GC问题。

我们的现象似乎和那很符合。

如果我们沿着这个思路做下去,具体怎样实施呢?

我们的WAS上部署了20个左右的Web应用,譬如Lucene全文检索、B2B行业数据同步等,都是通过Quartz的Job调度做的,当然还有很多其它调度。

当时,由我负责,通知相关负责人,将定时调度暂时去掉。

观察了几天,后来发现问题依然存在,不过时间有点随机了。

不过,最后还是发现OOM不是由Job调度引起的。

也就是说,我们这个方案是失败的。

而且,我们的很多想法都是臆测的,没有可靠的根据,也没有方向,再加上我是第一次处理这种问题,这导致后来查找问题的艰难。

但是,仔细想想,我们又能拿什么做依据呢?

出现OOM错误,我想大多数人想到的,除了JVM参数设置,就是内存泄漏。

其实,OOM发生有很多种情况,在IBM、Sun、BEA等不同虚拟机上,因为GC机制不一样,所以原因一般都不同,容易定位难度也不一样。

下文会谈到。

于是,我们干脆釜底抽薪分析问题吧:

用JProfiler检测。

二、按应用程序导致内存泄漏诊断,JProfiler检测

如果遇到OOM问题,我想大家都会想到内存检测工具,现在最可靠的还是下面三种分析工具:

Borland的OptimizeitSuite,Quest的JProbe,ej-technologies的JProfiler。

但面临三个问题:

1、三个都是商业产品,公司暂时没有买,必须自己下载,而且要找序列号。

2、工具必须支持AIX5.3+JDK1.42+WAS6.0,不是Windows平台。

3、工具必须在客户真实环境下部署,对客户的业务不能有冲击,也就是说部署测试工具前,必须做个大量测试,对工具非常熟练,遇到意外可以立即恢复现场。

Note:

项目上线后,而不是测试或试运行阶段遇到此类问题,非常考验人;另外一个,就是性能和可伸缩性问题,很可能把整个项目给毁了。

当我决定要这么做后,就立即动手查阅这些工具的官方文档,用emule下载,最终都下载到了。

试用后,最终选择了JProfiler4.03,比起其它工具,它界面美观、清晰、功能强大、集成度高(Heap,Memory,CPU,Thread都统一了)。

另外,JProbe没有AIX版本,这也是放弃它的一个原因。

JVM的Profiler原理,都是通过JVM内置的的标准C语言Profiler接口收集数据,然后通过Profiler工具的客户端展现。

也就是说各厂商的Profiler工具,都有两个部分,一个部分是ProfilerAgent,和JVM绑定,负责收集JVM内部数据,譬如方法调用次数、耗费时间等;另外一个部分就是Profilerfront-end。

通过Profiler工具的自定义local或remote协议传输到front-end,其实,我们最常用的JavaIDE的debug功能就是在此基础上的(JPDA)。

(JProfiler的截图http:

//www.ej-...er/screenshots.html)。

下面是Sun官方文档:

JDK1.42及以前是JVMPI:

JDK1.5是JVMTI:

具体到JProfiler的配置上,专门针对JDK1.4和1.5的JVM配置差别很大。

我用的JProfiler是4.31版本,透露给大家一个万能序列号吧(这东西不太好找),对各版本应该都支持。

深入了解Java,这类工具是不可少的:

Name:

LicenseforYou

LinceseCode:

A-G667#42616F-10kg1r134fq9m#2217

为了保证真实环境的检测成功,我做了大量的试验,譬如:

1、Windows系列的本地、远程测试。

2、AIX的远程测试。

3、Tomcat5.0、WebLogic8.14、WebSphere6.02,以及上述两种方式的组合测试,排列组合,场景不下10个。

当时也参阅了大量JVM文档,JProfiler官方几百页英文文档,辅助的JProbe对照。

而且也制造过内存泄漏造成的OOM场景。

当然,要是在几个月前,在客户那边部署的测试环境时,就进行测试该多好啊。

相关主题推荐

∙WebSphereApplicationServer中的内存泄漏检测与分析

(2)

∙WebSphereApplicationServer中的内存泄漏检测与分析

(1)

∙WebSphere配置JSP泄漏漏洞

∙IBMWebSphere配置JSP泄漏漏洞

∙WebSphereApplicationServer中的内存泄漏检测与分析:

第2部分

(1)

∙WebSphere应用服务器内存泄漏探测与诊断工具选择最佳实践

(1)

∙WebSphereApplicationServer中的内存泄漏检测与分析:

第1部分

(1)

∙WebSphere应用服务器内存泄漏

∙WebSphereJVMclassloader内存泄漏

本主题由olivia于2012-7-1709:

09移动

2#

二星级会员52055687发表于2008-2-2917:

15|只看该作者

在公司内部,我用JProfiler测试了我们当时部署的几个应用,没有发现内存泄漏,所以,我们最怀疑的是就是CMS系统。

因为出问题的那个WAS上它占去了90%的负荷(我们有多台AIX、WAS服务器)。

该CMS超级庞大,感觉著名的赛迪网就用它,当时该CMS厂商给我们部署都花了快一个月。

所以再重新部署一套测试环境也挺困难。

另外,CMS提供商不给lisence。

现在测试,客户早就对我们恼火了,当然不怎么配合,这对我们工作的开展就有很大的挑战。

在大致可以确定万无一失的情况下,我们最终决定在客户的真实环境下测试。

也就是让JProfiler的agent端直接在WAS的JVM里面启动(北京IDC),然后远程(大连)监控。

本来该模式在另外几个应用的测试都通过了(因为北京IDC那边好几台AIX服务器)。

但一部署上,客户的一些编辑用CMS时就感觉超级慢,尽管我们用了JProfiler的最小负载模式。

半个小时后,客户实在无法忍受,打电话过来,又把我们部长和经理训了一顿,还要写书面报告。

我们被迫马山中止测试,恢复现场。

虽然JProfiler也支持客户那边的环境,但还是有bug,至少负载一高就有严重的性能问题,几乎导致系统挂起,这是我当时没有料到的。

JProfiler一启动,WAS的启动时间就由原来的3分钟降到10分钟,而且系统响应明显变慢,我们具体的环境如下(排列组合恐怕不下20种):

1、AIX5.3,PowerPC64位(不是32位)

2、WebSphere6.0

3、IBMJVM1.42

4、Remote模式

我后来仔细读了一下JProfiler的changeLog,发现对上面的环境支持不够也很正常,因为官方在最近的4.3.x版本下陆续有对IBMJVM和Websphere6.0的features和bugfix:

http:

//www.ej-

进行到这一步,我忽然觉得无计可施了,此时已经过了三周。

上面的策略,我认为是很正统的处理方法。

谁怪我们当初项目上线时没有进行充分的测试呢?

其实,这类测试没做也正常,OOM这类问题谁都无法预测。

到这个时候,我想肯定有人会问我?

你知道导致JVM的OOM有几种情况吗?

在当时,我想到了以下五种:

1、JVM的heap最小、最大值没有设,或不合理。

2、JVM的maxPermSize没有设置(这个IBM的JVM没有,一设置JVM就起不来)。

对于Sun和BEA的JVM,以上两种参数设置,可以排除90%以上的非程序内存溢出导致的OOM。

3、程序内存泄漏

4、有的JVM,当在80%的CPU时间内,不能GC出2%的heap时,也发生OOM(IBM的JVM就是,但我没有验证)

5、JVM本身内存泄漏(JVM有bug不是不可能)

现在的难题是,如果是那个可怕的CMS程序本身有内存溢出,在产品环境下,我们怎么去验证?

我们自己开发的10来个web应用,测试并不是很难,在公司测试都可以。

但是,我现在最想解决的,就是CMS测试的问题。

而且,在我们那种环境下,该CMS产品供应商并没有透露成功案例。

其实,最后发现,并不是内存泄漏造成的,因为我们的heap走势都很平稳。

纳闷的是,有1000M的heap,每次在heap只被占用400来M时就发生OOM,没有任何预兆。

大家猜猜,会是什么原因?

这个问题我到后面相关章节再说吧。

既然我们所有的矛头都指向那个可怕的CMS系统,现在就是考虑隔离的问题。

如果我们验证这个问题是CMS造成的,那么大部分责任就应该由CMS厂商承担。

既然CMS我们不敢移(费劲,而且客户在正式用),那我就移我们开发的10来个web系统吧。

三、移出除CMS系统以外的所有应用

说起来容易啊,做呢?

隔离(移动)工作由我负责,具体涉及到10来个相关负责人。

转移工作,必须处理好很多问题,就说几个印象最深的吧:

1、某些应用,如Blog和BBS,都涉及到文件、图片上传目录和产品本身的环境,如JDBC连接池、Cache位置。

2、目标服务器本身的环境,WAS安装环境、网络等。

3、移植时的先后顺序、调度,各应用内部本身的约束关系。

4、移植后的测试。

当然,还有一个最严峻的问题,客户允许我们这么做吗?

对它们目前运行的系统有多大影响?

风险如何评估?

这个工作持续了一天,已经完成了80%的工作,到第二天,客户又恼火了:

WAS又宕机了。

为什么?

这确实是WAS的一个bug:

WAS的后台随便一操作,heap就会突然上升几百M,导致JVM内存不够。

不过WAS撑住的话,过半小时后就会降下来,我估计是WAS后台对用户操作状态、文件都缓存到Session里面。

你们可以检查类似这样的一个文件夹:

d:

\IBM\WebSphere\AppServer\profiles\AppSrv01\wstemp,我不知道为什么WAS不主动去清除它,它偷偷的就上升到几个G,系统硬盘可能不久就后就会空间不足,WAS莫名迟缓、最后死掉。

听过WAS6.0以前这个目录更夸张。

大家见我附件的截图WAS_Console.png那个尖峰。

咋办?

经理也已经不敢让我们继续铤而走险了。

这个方案最终又以失败告终。

不过,最后我们还是发现问题出在CMS上。

我们以前把这个问题向CMS技术支持反映,有大量依据和现象,并且把相关日志都给它们。

过了两天,他们最后竟然只回了一句话“从给我的两个日志来看,没有找到任何与XXX有关的东西....”。

TMD!

我真的很生气,它们的产品都折磨我们半年之久了。

不过,看他们对IBM的WAS和JVM也不懂,我也就不想再说什么了。

下面是我的邮件,公司机密部分都隐去了:

3#

二星级会员52055687发表于2008-2-2917:

15|只看该作者

引用

附件是我们这段时间服务器宕机的日志。

我们用IBMPatternModelingandAnalysisToolforJavaGarbageCollectorVersion1.3.2分析了一下虚拟机日志,没有发现是内存泄漏导致;用IBMHeapAnalyzerVersion1.4.4分析heap文件,也没有发现很可疑的内存泄漏。

我想以前你们也这样做过,现在我们分析错误日志,发现有一个现象,在宕机时,总是找不到文件,我看就是Websphere或是AIXIO资源不够,不知道是什么导致的。

但是,我们自己的应用,基本上没有什么IO,除了一次load几个配置文件。

不过,我觉得你们WCM的IO操作挺多的,不知道你对日志有什么新的发现。

客观的说,这几个月来,宕机那台服务器,除了你们的XXX,就以论坛和blog为主,而且他们都是开源的。

在频繁宕机的06年11月份,我们的论坛和blog还没有上线。

现在我们不得不每天晚上11点定时重启,但这也不是长久之计。

现在,我们进行分离遇到很大阻力,原来想把你们的XXX单独分离出来,在当前的环境下,不是很现实,如安装、测试(负载、定时服务),所以现在分离我们自己的应用,但当前在产品环境下,客户方阻力也很大。

希望尽快能够得到你们的问题建议和方案。

文中说到了IBM的两个分析工具,这也是我们后来的救星:

我们就是需要这种离线分析工具,因为实时检测已经证明不现实。

但我始终对该分析出来的结果抱怀疑态度,直到我去深入IBM的JVM以及和IBM的技术支持交流......

柳暗花明啊,至少看到了一点希望,不过最后我们还是失望而返。

四、用IBM的HeapAnalyzer和GarbageCollector检测

找到这两个工具,已经是够费劲了,因为以前找的IBMHeapRoot工具,让我对这类工具很失望。

而且,这两个工具,只有在IBM的TechinicalSupport网站能够搜索到,但很不容易,因为那两个工具,并不是象IBM的Websphere产品那样宣传,它只在IBMTechinicalSupport文章的某些角落里出现。

要知道,TechinicalSupport是IBM很重要的收入来源,这类文档,他们并不会让你很轻易就拿到,比起BEAWLS的支持网站dev2dev差远了。

具体诊断细节我就不详述了。

我认为,IBM的WAS或JVM出了性能和OOM问题,这两个工具是最有效的,而且是离线分析工具,比起那些实时Profiler工具,某些场合有绝对的优势:

譬如我们目前的产品环境,你只能分析宕机后的日志,实时分析前面已经验证是不可行的。

从日志分析,我们最终得出结论,我们购买的CMS系统有严重的碎片(大对象)问题,而该问题是OOM的罪魁祸首,而且IBM工程师也得出了同一结论。

不过,在起先我们得出这一结论一周后,我还始终不相信heap碎片会导致OOM,直到IBM工程师总是向我强调。

我想很多人也是不太相信,因为大多数人用的都是Sun的JVM,譬如Windows、Solaris上的hotspot。

而且,SunJVM出问题,如果是配置的问题,一般通过配置heap最大最小值,以及maxPermSize都可以解决。

Heap碎片导致的OOM,只有BEA的JRockit和IBMJVM上发生,不过JRockit有专门文档说明,而且很容易找到(就在jdk的文档里面)。

配置heap最小最大值,我想大多数人都有经验。

对于Sun的JVM来说,一般可以设置heap最大最小值一致,也是推荐的做法。

因为它的GC策略默认是复制、分代算法。

也就是说,它会将heap分成不同的几个区,譬如SolarisJVM中最上面有两个大小相等的区。

GC时刻,将一个区的存活对象复制到另外一个对等区,垃圾对象就算遗弃了。

这样在heap里面,就不存在碎片问题。

另外,根据Java对象的存活期不同,将之转移到不同的区(Tenured区),存活最长的在最底部(火车算法),这也就是分代模型。

具体请参考官方文档:

对于maxPermSize(PermanentGeneration),主要和那些加载到JVM里面的JavaClass对象相关,它的空间不是在JavaHeap里面分配。

如果你当前的heap有1000M,permSize是200M,那么JVM至少占用1200M。

在这个空间内的对象的生存期和JVM是一样的,譬如JDK的核心类库,它们被SystemClassloader加载到JVM的MethodArea(方法区)后,就不会被GC掉的,这些对象一般是Class对象,而不是普通的实例对象,也就是JVM的元数据。

我们在用反射时经常用到它们。

所以,对于现在象Spring、Hibernate这些框架经常通过反射创建实例,可能对maxPermSize要求就大了,缺省的64M很多时候是不够的,特别是对于应用服务器里的应用,象JSP就会产生和加载很多classes。

不过,如果是它导致的OOM,一般会有类似permsize提示。

但是,对于IBM的JVM,情况就完全不一样。

它的默认GC策略并没有采取复制、分代。

这个可以从GC日志分析出来。

它不像Sun的JVM那样,有个单独的方法区,它的方法区就放在JavaHeap里面。

JVM规范里面并没有要求方法区的必须存放的位置,因为它只是一个JVM实现问题。

在IBM的JVM里面,这些对象一般分配在称为k-cluster和p-cluster里(cluster又是属于Heap),而后者一般是临时在heap里面申请。

并且,这些cluster是不能GC,或是被移动重排的(Compact过程)。

这就导致JavaHeap里面就如同马蜂窝,但不同的蜂孔又不能合并,于是,当我们程序里面产生一个大对象,譬如2M的数组(数组必须分配在连续的内存区)时,就没有可分配空间了,于是就报告OOM。

这些不能被移动的cluster就称为所谓的碎片。

此时,JVM的Heap利用率可能不到50%。

当然,通过一定时期的GC日志,可以计算出cluster的合理大小(专门在JavaHeap的底部),另外,还可以为这些大对象专门分配大对象区的(超过64k的对象)。

通过上面的理论介绍,我想大家一定知道了为什么IBM的JVM里面不推荐heap的最大最小值相同,因为这样碎片问题会非常严重:

如果我们每次大对象申请内存时,heap都扩展5%,譬如50M,碎片问题很大程度上可以避开,程序性能也高些(寻找可用空隙和分配耗时,以及每次GC时间拉长)。

以上的具体阐述,请参考我在上文推荐的几个URL,另外再推荐三个宝贵的链接:

...s=utf-8&lang=en

...DocId=2447476A10000(IBM技术支持告诉我的,太重要了!

...DocId=2847476B08000

4#

二星级会员52055687发表于2008-2-2917:

16|只看该作者

我想大家应该会问:

我怎么能够肯定我的OOM问题是heap碎片造成的呢?

下面的方法可以验证。

在OOM发生时,JVM会产生一个heapdump文件。

然后用GarbageCollector分析出该OOM发生时刻,JVM去申请的空间,譬如约235k。

此时,你再用HeapAnalyzer去分析此时的heap快照里面的gapsize大小(空隙大小)和各自的可用数目。

你会发现,大于235k的空隙个数为0。

这就是碎片导致OOM的证据。

另外,有人会问:

我怀疑我的OOM是因为程序内存泄漏造成的,怎么去验证?

你可以用HeapAnalyzer分析发生OOM时刻的heap快照,工具会罗列出哪些对象怀疑有内存泄漏,譬如Cache对象都非常大(但你可以确定它不是内存泄漏)。

另外,分析这次宕机(从这次虚拟机启动到宕机这段时间)的heap走势,如果曲线明显是向上倾斜,也就是那种典型的内存泄漏图,就有可能是内存泄漏。

当然,还必须结合heap快照。

内存持续上升在JVM开始一段时间很正常,因为JVM对第一次访问到的Class对象,譬如一个典型的Web应用,就有jdk的class、Spring或Hibernate的class对象,它们都会被缓存下来(ClassLoader原理),一般均不会被GC。

当大多数class对象缓存差不多(当然还可能有一些Singleton对象,不过不怎么占分量),JVM的He

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 中考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1