当前位置:文档之家› WebSphere 内存泄漏 Java虚拟机收藏

WebSphere 内存泄漏 Java虚拟机收藏

WebSphere 内存泄漏 Java虚拟机收藏
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 的分析工具得到的截图。对截图的分析,留给后面对应的部分吧。

服务器不稳定、宕机问题,拖延到最后,客户愤怒了,公司高层也害怕了,部门还专门成立了八人攻关组。当然了,我当时的压力也非常大,因为我是技术负责人,也就是实实在在干活、想主意的。

服务器诊断那段时间,从前到后,我们也是沿着一条线走下来,虽然最后发现很多路都走不通。现在就按这个思路,也就是时间先后一步步叙述吧。我想,大家如果也碰到类似应用服务器诊断,应该思路差不多。

术语说明:

IBM Websphere Application Server:WAS,WebSphere本身是一个平台,产品家族OutOfMemoryError:OOM,内存泄漏,内存溢出

Gabage Collection:GC,自动垃圾回收

Content Management System: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 的Optimizeit Suite,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工具,都有两个部分,一个部分是Profiler Agent,和JVM绑定,负责收集JVM内部数据,譬如方法调用次数、耗费时间等;另外一个部分就是Profiler front-end。通过Profiler工具的自定义local或remote协议传输到front-end,其实,我们最常用的JavaIDE的 debug功能就是在此基础上的(JPDA)。(JProfiler的截图https://www.doczj.com/doc/df6643798.html,/p ... er/screenshots.html)。

下面是Sun官方文档:

JDK1.42及以前是JVM PI:https://www.doczj.com/doc/df6643798.html,/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html

JDK1.5是JVM TI:https://www.doczj.com/doc/df6643798.html,/j2se/1.5.0/docs/guide/jvmti/jvmti.html

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

我用的JProfiler是4.31版本,透露给大家一个万能序列号吧(这东西不太好找),对各版本应该都支持。深入了解Java,这类工具是不可少的:

Name: License for You

Lincese Code: A-G667#42616F-10kg1r134fq9m#2217

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

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

2、AIX的远程测试。

3、Tomcat5.0、WebLogic8.1

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

当时也参阅了大量JVM文档,JProfiler官方几百页英文文档,辅助的JProbe对照。而且也制造过内存泄漏造成的OOM场景。

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

相关主题推荐

?WebSphere Application Server 中的内存泄漏检测与分析(2)

?WebSphere Application Server 中的内存泄漏检测与分析(1)

?WebSphere配置JSP泄漏漏洞

?IBM WebSphere配置JSP泄漏漏洞

?WebSphere Application Server 中的内存泄漏检测与分析: 第 2 部分(1)

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

?WebSphere Application Server 中的内存泄漏检测与分析: 第 1 部分(1)

?WebSphere应用服务器内存泄漏

?WebSphere JVM classloader 内存泄漏

本主题由 olivia 于 2012-7-17 09:09 移动

2#

二星级会员52055687发表于 2008-2-29 17: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,Power PC64位(不是32位)

2、WebSphere6.0

3、IBM JVM1.42

4、Remote 模式

我后来仔细读了一下JProfiler的changeLog,发现对上面的环境支持不够也很正常,因为官方在最近的4.3.x版本下陆续有对IBM JVM和Websphere6.0的features 和bug fix:https://www.doczj.com/doc/df6643798.html,/download/jprofiler/changelog.html

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

上面的策略,我认为是很正统的处理方法。谁怪我们当初项目上线时没有进行充分的测试呢?其实,这类测试没做也正常,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-29 17:15 | 只看该作者

引用

附件是我们这段时间服务器宕机的日志。我们用IBM Pattern Modeling and Analysis

Tool for Java Garbage Collector Version 1.3.2分析了一下虚拟机日志,没有发现是内存泄漏导致;用IBM HeapAnalyzer Version 1.4.4 分析heap文件,也没有发现很可疑的内存泄漏。

我想以前你们也这样做过,现在我们分析错误日志,发现有一个现象,在宕机时,总是找不到文件,我看就是Websphere或是AIX IO资源不够,不知道是什么导致的。但是,我们自己的应用,基本上没有什么IO,除了一次load几个配置文件。不过,我觉得你们WCM的IO操作挺多的,不知道你对日志有什么新的发现。

客观的说,这几个月来,宕机那台服务器,除了你们的XXX,就以论坛和blog为主,而且他们都是开源的。在频繁宕机的06年11月份,我们的论坛和blog还没有上线。现在我们不得不每天晚上11点定时重启,但这也不是长久之计。

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

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

文中说到了IBM的两个分析工具,这也是我们后来的救星:我们就是需要这种离线分析工具,因为实时检测已经证明不现实。但我始终对该分析出来的结果抱怀疑态度,直到我去深入IBM的JVM以及和IBM的技术支持交流......

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

四、用IBM的HeapAnalyzer和GarbageCollector检测

找到这两个工具,已经是够费劲了,因为以前找的IBM HeapRoot工具,让我对这类工具很失望。而且,这两个工具,只有在IBM的Techinical Support网站能够搜索到,但很不容易,因为那两个工具,并不是象IBM的Websphere产品那样宣传,它只在IBM Techinical Support文章的某些角落里出现。要知道,Techinical Support是IBM很重要的收入来源,这类文档,他们并不会让你很轻易就拿到,比起BEA WLS的支持网站dev2dev差远了。

具体诊断细节我就不详述了。我认为,IBM的WAS或JVM出了性能和OOM问题,这两个工具是最有效的,而且是离线分析工具,比起那些实时 Profiler工具,某些场合有绝对的优势:譬如我们目前的产品环境,你只能分析宕机后的日志,实时分析前面已经验证是不可行的。

从日志分析,我们最终得出结论,我们购买的CMS系统有严重的碎片(大对象)问题,而该问题是OOM的罪魁祸首,而且IBM工程师也得出了同一结论。不过,在起先我们得出这一结论一周后,我还始终不相信heap碎片会导致OOM,直到IBM工程师总是向我强调。

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

Solaris上的hotspot。而且,Sun JVM出问题,如果是配置的问题,一般通过配置heap最大最小值,以及maxPermSize都可以解决。Heap碎片导致的OOM,只有BEA的 JRockit和IBM JVM上发生,不过JRockit有专门文档说明,而且很容易找到(就在jdk的文档里面)。

配置heap最小最大值,我想大多数人都有经验。对于Sun的JVM来说,一般可以设置heap最大最小值一致,也是推荐的做法。因为它的GC策略默认是复制、分代算法。也就是说,它会将heap分成不同的几个区,譬如Solaris JVM中最上面有两个大小相等的区。GC时刻,将一个区的存活对象复制到另外一个对等区,垃圾对象就算遗弃了。这样在heap里面,就不存在碎片问题。另外,根据Java对象的存活期不同,将之转移到不同的区(Tenured区),存活最长的在最底部(火车算法),这也就是分代模型。具体请参考官方文档:

https://www.doczj.com/doc/df6643798.html,/docs/hotspot/gc1.4.2/

对于maxPermSize(Permanent Generation),主要和那些加载到JVM里面的Java Class对象相关,它的空间不是在Java Heap里面分配。如果你当前的heap有1000M,permSize是200M,那么JVM至少占用1200M。

在这个空间内的对象的生存期和JVM是一样的,譬如JDK的核心类库,它们被System Classloader加载到JVM的Method Area(方法区)后,就不会被GC掉的,这些对象一般是Class对象,而不是普通的实例对象,也就是JVM的元数据。我们在用反射时经常用到它们。所以,对于现在象Spring、Hibernate这些框架经常通过反射创建实例,可能对maxPermSize要求就大了,缺省的64M很多时候是不够的,特别是对于应用服务器里的应用,象JSP就会产生和加载很多classes。不过,如果是它导致的OOM,一般会有类似 perm size提示。

但是,对于IBM的JVM,情况就完全不一样。它的默认GC策略并没有采取复制、分代。这个可以从GC日志分析出来。它不像Sun的JVM那样,有个单独的方法区,它的方法区就放在Java Heap里面。JVM规范里面并没有要求方法区的必须存放的位置,因为它只是一个JVM实现问题。

在IBM的JVM里面,这些对象一般分配在称为k-cluster和p-cluster里(cluster又是属于Heap),而后者一般是临时在 heap里面申请。并且,这些cluster是不能GC,或是被移动重排的(Compact过程)。这就导致Java Heap里面就如同马蜂窝,但不同的蜂孔又不能合并,于是,当我们程序里面产生一个大对象,譬如2M 的数组(数组必须分配在连续的内存区)时,就没有可分配空间了,于是就报告OOM。这些不能被移动的cluster就称为所谓的碎片。此时,JVM的Heap利用率可能不到50%。

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

通过上面的理论介绍,我想大家一定知道了为什么IBM的JVM里面不推荐heap

的最大最小值相同,因为这样碎片问题会非常严重:如果我们每次大对象申请内存时,heap都扩展5%,譬如50M,碎片问题很大程度上可以避开,程序性能也高些(寻找可用空隙和分配耗时,以及每次GC时间拉长)。

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

https://www.doczj.com/doc/df6643798.html,/support/doc ... s=utf-8&lang=en

https://www.doczj.com/doc/df6643798.html,/cn/suppor ... DocId=2447476A10000(IBM 技术支持告诉我的,太重要了!)

https://www.doczj.com/doc/df6643798.html,/cn/suppor ... DocId=2847476B08000

4#

二星级会员52055687发表于 2008-2-29 17:16 | 只看该作者

我想大家应该会问:我怎么能够肯定我的OOM问题是heap碎片造成的呢?下面的方法可以验证。

在OOM发生时,JVM会产生一个heapdump文件。然后用GarbageCollector分析出该OOM发生时刻,JVM去申请的空间,譬如约 235k。此时,你再用HeapAnalyzer去分析此时的heap快照里面的gap size大小(空隙大小)和各自的可用数目。你会发现,大于235k的空隙个数为0。这就是碎片导致OOM的证据。

另外,有人会问:我怀疑我的OOM是因为程序内存泄漏造成的,怎么去验证?

你可以用HeapAnalyzer分析发生OOM时刻的heap快照,工具会罗列出哪些对象怀疑有内存泄漏,譬如Cache对象都非常大(但你可以确定它不是内存泄漏)。另外,分析这次宕机(从这次虚拟机启动到宕机这段时间)的heap走势,如果曲线明显是向上倾斜,也就是那种典型的内存泄漏图,就有可能是内存泄漏。当

然,还必须结合heap快照。

内存持续上升在JVM开始一段时间很正常,因为JVM对第一次访问到的Class 对象,譬如一个典型的Web应用,就有jdk的class、Spring或Hibernate的class对象,它们都会被缓存下来 (ClassLoader原理),一般均不会被GC。当大多数class 对象缓存差不多(当然还可能有一些Singleton对象,不过不怎么占分量),JVM 的Heap就平稳了,呈一水平波浪或锯齿线。

如果可以用JProfiler这类工具实时监控,就更容易确诊了。

经过一番周折,我们终于看到了一线希望了。

在一定的准备后,我们决定对WAS进行性能调优了。WAS的调优参数,可以分为两个部分:JVM级别和WAS级别:

JVM:主要是GC和Heap。

WAS:Thread Pool,JDBC DataSource。

当然要调节,你需要明白你的目标是什么,调节依据是什么,怎么计算,绝对不是凭空想象的,譬如heap最小值1024M,日志证明,该参数非常不适合我们的环境。具体细节,留给后文吧。

战战兢兢地,中午12:00,我们给产品环境下的WAS调节参数、重启,同时优化了AIX的IO相关参数。

我试着设置了一下JVM的k-cluster和p-cluster。下午15:00左右,WAS挂了,AIX也挂了。这下麻烦可大了。我们都慌了,马山客户的老总就来电话了,一阵哗哗啦啦。实在无奈,让客户那边工作人员通知机房(服务器托管处)工作人员重启AIX。我也不得不强行更改刚才的参数,立即设为另外一个值。

其实,我把那个两个cluster值确实设置太大了,我把它们设置为推荐值的5倍,譬如p-cluster是65k×110%×5。另外一个愚蠢的设置就是把最小heap设置为

2048M(AIX有4G内存)。

后来我恢复到约正常的值,也就是去掉那个cluster的5,另外分配了一个30%的大对象区(如果1000M的heap,就是700M+300M)。

就这样,系统持续正常运行了三天,以前可是一天一down。当在三天后再次宕机时,我们都没有自信了。不得不通过AIX的cron,继续每天深夜11点的WAS定时重启。

不过,那次宕机,包括以后的几次宕机,再也没有出现OOM错误了,但系统依然不稳定。虽然我可以说OOM问题解决了,但领导和客户需要的并不是这种结果。

其实,在这个时候,我们已经发现我们系统的四大问题:

1、WAS和JVM参数:OOM问题

2、AIX的IO和Paging Spacing不足:AIX日志后来显示错误

3、AIX的WAS分区空间不够:WAS的日志膨胀一周就把那个opt分区塞满了。

4、应用程序的JDBC连接池:我们20来个应用,一个20 connections,DB2数据库有时被撑死。

也就是说,我们最初在客户那儿部署时,用的默认值根本不行。而且,部署涉及多人,人员之间出现断层。如果我们只是按OOM,无疑是走入死胡同,必须全局考虑!

但是,项目组实力薄弱,公司范围内就没有对AIX精通的。不过项目组原来有一个搞银行系统,在AIX下开发,就他熟悉些。我当时对AIX也比较陌生,你们从Linux转到AIX,你就知道它有多别扭了。命令都自定一套(也许因为是Unix元老吧),那个shell也超级别扭,而且参考书特少。不是自诩,我两年前负责一个高负载的Linux服务器管理一年多,也是玩得很转的。

就这样,他负责AIX的相关问题,我负责WAS相关的。

但是,现实环境,已经不允许我们再试验下去了。我们必须找到一条绝对可靠的对策!

这就是下文的CMS系统大迁移,服务器再次优化。

5#

二星级会员52055687发表于 2008-2-29 17:16 | 只看该作者

五、隔离CMS系统,服务器优化

从前面的介绍,大家应该记得,我们开始是固定CMS,分离其它应用,但遭遇失败。现在是反过来,干脆把CMS系统赶出WAS平台。

说实话,项目经理做这个决定,我认为已经是鼓出很大勇气了。

当时我们想在一个备用AIX机上安装CMS产品测试,但最后还是没有做成:CMS这类文章发布系统很难安装,也不好测试,又没有liscence,而且还有一堆准备工作。绝对没有著名的openCMS安装那么简单,当然功能远远比它复杂。而且,我们当时也低估了后来的工作,总觉得问题好解决。

在很遥远的06年中期,CMS厂商在客户那边一台AIX的Tomcat上部署了一套CMS产品。但当时客户执意要求将其跑在WAS上,也就是现在的情况。最开始,客户还要求我们必须用WAS的集群(我们买的就是WAS的ND版),无奈该CMS不支持。要是集群,又是死伤一遍。其实,现在想想,我们当时太被动,CMS这种东西,就供公司的几十个编辑用,一个普通Tomcat就完全够用。而且,把它和面向公网的Internet应用混在一起,完全没有必要。也许,被动是因为我的实力造成的。

我们决定背水一战时,已经做过周密的计划:某年某月某日晚上8:00......

CMS产品负责人现场切换

xx(我)负责WAS相关参数调整

yy负责AIX参数。

zz负责应用的测试

…..

总之,该行动涉及到客户方、产品提供商、公司高层、项目组。每个人都密切关注,不下20人。每个人都守在电脑前,随时听候调遣,当天晚上,我们都没有准备回家睡觉,大家齐心协力。

真没想到,整个式切换工作,一个小时就顺利完成!第二天,客户编辑打开浏览器,她们一定想不到昨晚大家准备经历一场厮杀….

系统持续平稳地运行了一周,然后是漫长的五一,我回湖北黄冈老家休息了八天。回来时,一切依旧。

当天晚上,我们这边主要做了两项工作:

1、JVM的Heap参数,共五个。

2、AIX的IO、Paging Space等共六个。

当然还有其他人的工作,譬如测试、监控。

还有一个非常重要的方面:JDBC连接池。我们原来是在每个Web应用里面独立

设置,这样20来个应用就有几百个DB连接,一不小心DB就给撑死。现在统一交由WAS内置DataSource处理,总共连接不到30个。其实,我们项目开始部署时,就是这样做的,但当时WAS内置的DataSource对 JTA(XA)支持有bug (这个和IBM技术支持确认过,但他们没有给予很好的解决方案),不过Datasource还是配好的。

但是这个工作已经属于WAS性能优化的主题了,而且优化值必须持续观察一段时间,通过专门的分析工具来计算。

优化本身,是一项很考验人的工作,我就简单说一下最实用方法吧,也许是专门针对IBM的产品。

1、清理归零WAS日志。然后启动WAS,生成日志(-verbose:gc默认是开的)

2、让WAS持续运行约两周,让JVM Heap占用曲线平稳一段时间即可(用IBM 的Garbage Collector分析观察)。

3、在AIX的shell里,产生heapdump.phd文件,也就是heap快照。命令:kill -3 pid (pid是WAS的PID,通过ps –ef查看),观察heap当时的碎片情况,是否需要单独分大对象区(一般不需要设置),特别是那个方法区Class对象大小(p-cluster参数)。

4、通过GC工具,观察GC平均时间、Heap实际占用情况。Note: GC是一个Stop The World过程,也就是说GC时系统对外不响应,多CPU也不例外。看你的应用实际需求了,GC持续时间和频率是矛盾的,另外还有性能考虑。一般Web应用,我想让GC持续时间(Pause time)调节到合理值就ok了,譬如0.2到0.4s。

5、根据3可以算出k-cluster值,它是工具推荐值的110%。

6、Heap的最小值是程序刚启动不久的占用值,譬如320M。切记:IBM JVM初始值太大非常不好。

7、Heap的最大值是系统平稳后的100/70。也就是说如果最大值是1000M,那么应该平稳时是700M,还有30%的空余。IBM的JVM默认情下的碎片问题,WAS 控制台下操作Heap猛增这种bug,你不得不堤防。Heap最大值不设,AIX下的WAS肯定OOM。

当然啦,我没有考虑到大对象区的计算(虽然我们的应用设置了专门的大对象区),包括IBM JVM支持的分代GC、并行GC,Heap每次expand百分比等。那些情况我们一般不常用,譬如,你的AIX平台一般不是16CPU吧?

一口气写到现在,我忽然觉得该收尾了。下面就说说我对这类工作的整体看法吧。

1、尽量在项目测试和试运行的时候就进行压力、性能测试,当正式投入使用后,如果发现类似问题,代价非常大。躲过算你运气好,一般来说,可能你们系统没多少人用,也不是核心业务系统,譬如一般的电子政务。

2、千万不要低估了技术风险,用IBM的系列产品尤其要慎重,出问题一定不要忘了技术支持。而且,查资料时,建议用google English,因为象WebSphere这类问题,很少有中文资料。

3、程序部署环境建立时,就要考虑到日后的正式环境,譬如AIX的Paging Space、IO、分区大小,默认值往往是不行的,而且在产品环境下改这些值,往往非常难。

4、在项目开发初期,就考虑到日志的问题,因为它分散到每个方法内,必须慎重定义好debug、info、warn、error级别,不要随便忽视异常(catch里面不记录),到真正程序出问题时,它就是我们的最重要的依据之一。当然这主要是功能性问题诊断。另外对于高负载网站,日志文件往往非常大,各级别日志千万不要混在一起,否则找问题就很困难了。

5、怎么说呢,别死扣技术,以为什么都可以通过技术解决。你看我们最大的问题就是把CMS给移到Tomcat下。你要是问我,为什么CMS产品会导致系统这么多的问题,我也不知道,到那时候,我确实也不想深入。我只要知道,赶出你这个应用,我的系统就好控制多了。而且,那个CMS系统,在Tomcat下,就是跑得服服帖帖的,非常稳定。难度是可恶的WAS?不过那CMS,据IBM工程师,包括我们二次开发,都觉得够烂了,每个jsp页面都打开、关闭DB connection(7年前的jsp开发模式),还有那么严重的大对象问题。

好了,以上总结的几点可能也不充分、深入,但如果你仔细读我这篇文章,应该有自己的想法。毕竟,只有经过思考的东西,才会属于自己。

java技术面试必问:JVM 内存模型讲解

java技术面试必问:JVM 内存模型讲解 今天我们就来聊一聊Java内存模型,面试中面试官会通过考察你对jvm的理解更深入得了解你的水平。在了解jvm内存模型前我们先回顾下,java程序的执行过程: java文件在通过java编译器生产.class 字节码文件,然后由jvm中的类加载器加载各个类中的字节码文件,加载完成后由jvm执行引擎执行,在整个加载过程中,jvm用一段空间来存储程序执行期间需要的数据和相关信息,这个空间就叫做jvm内存。 一、JVM 的重要性 首先你应该知道,运行一个 Java 应用程序,我们必须要先安装 JDK 或者 JRE 。这是因为 Java 应用在编译后会变成字节码,然后通过字节码运行在 JVM 中,而 JVM 是JRE 的核心组成部分。 二、优点 JVM 不仅承担了 Java 字节码的分析(JIT compiler)和执行(Runtime),同时也内置了自动内存分配管理机制。这个机制可以大大降低手动分配回收机制可能带来的内存泄露和内存溢出风险,使 Java 开发人员不需要关注每个对象的内存分配以及回收,从而更专注于业务本身。 三、缺点 这个机制在提升 Java 开发效率的同时,也容易使 Java 开发人员过度依赖于自动化,弱化对内存的管理能力,这样系统就很容易发生 JVM 的堆内存异常、垃圾回收(GC)的不合适以及 GC 次数过于频繁等问题,这些都将直接影响到应用服务的性能。 四、内存模型 JVM 内存模型共分为5个区:堆(Heap)、方法区(Method Area)、程序计数器(Program Counter Register)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)。 其中,堆(Heap)、方法区(Method Area)为线程共享,程序计数器(Program Counter Register)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)为线程隔离。 五、堆(Heap) 堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。 堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 区和 Survivor 区,最后 Survivor 由 From Survivor 和 To Survivor 组成。

水上垃圾清理装置 论文

水上垃圾清理装置 1 论文摘要 1.1中文摘要 摘要 随着我国现代化进程的加快、垃圾产生量的增加,水上漂浮垃圾的数量也日益增多,而现有人工清理方式不仅效率低下,而且带有一定的危险性。鉴于此,我们设计了这个水上垃圾清理装臵,以实现对漂浮垃圾环保、高效的收集。【关键词】垃圾收集清理环保节能

目录 1 论文摘要 (1) 1.1 中文摘要 (1) 1 引语 (1) 2 作品简介 (1) 3 作品分类 (1) 4 设计目的 (1) 5 设计基本思路 (1) 6 作品原理简介 (1) 7 作品模型图片及照片 (1) 8 使用说明 (3) 9 作品主要创新点 (3) 10 作品可行性 (4) 11 技术特点优势分析 (4) 12 适应范围 (5) 13 市场分析 (5) 14 经济效益预测 (5) 15 推广价值 (5) 16 结束语 (7)

1 引语 自古中华民族就以秀丽的山河文明于世,而在改革开放三十多年之后,我们要以更加美好的景色欢迎世界各地的友人。但随着现代化的加快,我们看到的却已不是美丽的山河,而是工业文明所导致的环境污染,以及由此所引发的种种疾病,灾难。有鉴于此,我们设计了这个水上垃圾清理装臵,希望以此为祖国环境保护尽自己的绵薄之力。 2作品简介 本作品利用船只自身行进过程与水面的相对运动,带动垃圾收集器工作,达到收集清理水面漂浮垃圾的目的。广泛适用于河面,湖面,海面等垃圾比较多的区域。具有环保、无污染、收集效率高、操作简单、成本低廉等特点。 3作品分类 机械控制与能源化工类 4设计目的 本作品是专为清理河流湖泊及海面上的漂浮垃圾而设计的。机械化的设计不仅无需外加动力,美观的外形也成为水上一道靓丽的风景线,亦可起到宣传环保意识的作用。 5设计基本思路 河流湖泊漂浮垃圾多,人工清理费时费力。本作品主要利用船只作为收集清理载体,配合本作品加以简单改装,即可实现利用船只的闲余能源清理漂浮垃圾的目的。 6作品原理简介 船只前进过程中,水流的冲击力使位于船只后方的叶轮转动,叶轮带动传送带的转动。传送带上的传送收集袋在随传送带转动的过程中把位于收集口后方的垃圾收集起来。随着传送带的转动,传送收集袋运动至后方的收集器上方,并随传送带转动,将垃圾倒入收集器中。此收集过程往复循环。 7作品模型图片及照片

java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案

大概原因,就是java堆内存不足以运行JVM,需要增加内存。 网上搜索此问题,大部分都是针对某个程序进行修改JVM内存的解决方法,比如eclipse,等。试问,若是其他程序出现问题了呢? 现在给出一个全局的java虚拟机修改内存的方法。在WIN XP,WIN 7,WIN8都可以。 解决方案:增加一个系统环境变量 变量名:_JAVA_OPTIONS 变量值:-Xmx512M 保存后,就OK!! 下面给出关于java堆内存的一个介绍,这是一个英文网页的翻译过来的。 关于java堆内存: Java -Xmx is the configuration parameter to control the amount of memory Java uses on a system. Basically these settings are there to control the Heap memory size of Java. There are two settings related to Java heap memory: ?-Xmx to set the maximum heap memory size ?-Xms to set the minimum heap memory size Tips to set the Java heap memory size

Managing the Java heap memory size for a server is very crucial as the whole performance depends on this memory size, off course there are other factors which affects the performance. So let’s see how you can set these parameters to control the Java heap memory size. Do not set -Xmx to too small value If you set -Xmx too small for your server then your application may not work properly and you may get Out of memory exception. So never set this too small as this is the maximum amount of memory you are allocating for Java and it cannot utilize memory beyond the set value. It is always advisable to set -Xmx to a higher value if you have enough memory space available on your server. On the other hand if you set -Xmx value to a higher value your other resources will not be able to perform well as you have already reserved some of your memory for Java. So before setting the maximum heap size memory just check how much memory is free. To do so, stop your application server and check the free memory and accordingly you can set the maximum memory size. For example if you have 512M free memory then you can set heap memory to 300M safely i.e. -Xmx300m.

Java虚拟机(JVM)参数配置说明

Java虚拟机(JVM)参数配置说明 在Java、J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能。 JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置。但是在生产环境中,为了提高性能,往往需要调整这些参数,以求系统达到最佳新能。另外这些参数的配置也是影响系统稳定性的一个重要因素,相信大多数Java开发人员都见过“O utOfMem ory”类型的错误。呵呵,这其中很可能就是JVM参数配置不当或者就没有配置没意识到配置引起的。 为了说明这些参数,还需要说说JDK中的命令行工具一些知识做铺垫。 首先看如何获取这些命令配置信息说明: 假设你是windows平台,你安装了J2SDK,那么现在你从cmd控制台窗口进入J2SDK安装目录下的bin目录,然后运行java命令,出现如下结果,这些就是包括java.exe工具的和J VM的所有命令都在里面。 ----------------------------------------------------------------------- D:\j2sdk15\bin>java Usage: java [-options] class [args...] (to execute a class) or java [-options] -jar jarfile [args...] (to execute a jar file) where options include: -client to select the "client" VM -server to select the "server" VM -hotspot is a synonym for the "client" VM [deprecated] The default VM is client.

JAVA内存分析指引201007_V0.2

JA V A内存分析指引 2010-07 1 环境说明 根据一般项目部署情况,生产环境以WebSphere5和WebSphere6为主,本文中所涉及环境变量也主要采用WebSphere的相关环境变量。 WebSphere5安装目录(默认): Windows:C:\Program Files\WebSphere\AppServer AIX:/usr/WebSphere/ AppServer WebSphere5日志路径 Windows:C:\Program Files\WebSphere\AppServer\logs\server1 AIX: /usr/WebSphere/ AppServer/logs/server1 WebSphere6安装目录(默认): Windows:C:\Program Files\IBM\WebSphere\AppServer AIX:/usr/IBM/WebSphere/AppServer WebSphere6日志路径: Windows:C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\logs\server1 AIX: /usr/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/server1 2 内存溢出原理 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。 为了解决Java中内存溢出问题,我们首先必须了解Java是如何管理内存的。Java的内存管理就是对象的分配和释放问题。在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的。 Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。GC为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。

用于近海垃圾收集的两栖机器人

用于近海垃圾收集的两栖机器人 摘要:设计方案来源于水陆两用垃圾收集船,考虑到沙滩地形的复杂性,采用履带式,使其在沙滩行走时更具稳定性。设计垃圾收集两栖机器人主要为打捞水面垃圾和陆地垃圾收集提供操作灵活的设备。机械设备是垃圾收集两栖机器人的重要组成部分,该方案重点介绍船体与履带、中心转塔支柱、垃圾收集器等的机械构造的设计。 正文: 机械机构设计: 该作品主要是以船为主体,履带不仅提供在沙滩上的动力,而且提供水面上前进的动力。 船体与履带: 船的基本尺寸为:0.2m*0.15m

穿的周身为塑料密封材料,穿的上部(即船的顶部甲班为太阳能板)船身为流线型减轻阻力 船体的内部构造如下图所示: 履带采用四轮、四马达设计,船体内部用齿轮进行履带轮的传动,中间为蓄电池及控制电路 履带轮较之履带突出一部分改装为轮桨腿式,在水面上靠此

结构前进。轮浆腿的材料为铝片 形状如下图所示: 也可采用我们先前讨论的方案进行设计。 垃圾收集器: 水面垃圾收集: 海面垃圾收集器外观呈簸箕形状,三面用铝板做成,而铝板上被扎成“千疮百孔”,上面有无数个孔眼,以让海水通过。用铝板的目的是:铝板质轻且不易生锈,成本较低 形状如下图的中间部分。

垃圾收集器与中心与中心转塔支柱连在一起,工作时将它放下与海面平行,船驶过时将漂浮的垃圾收入囊中。不工作时利用中心转塔支柱将其抬起。 垃圾收集器采用收割机式滚筒 两个马达,独立的动力系统 材料均为橡胶

中心转塔支柱: 中心转塔支柱采用吊桥式结构,自由度少(两个自由度),未定性更高,材料主要为铝片、细钢丝、滑轮等,成本低。 电源系统: 主要由蓄电池及太阳能板供给能源 蓄电池采用铅蓄电池 电压为10v 尺寸44*35*90mm 太阳能板的尺寸船体甲板一样 容量为150MA 电压为6v

水面垃圾清理机器说明书

专业课程设计说明书 题目:水面垃圾清理机器的设计 指导教师:何韶君 班级:机械设计制造及其自动化专业142班设计者:杨威威 学号:2014031224 校院:大连民族大学机电工程学院

目录 专业课程设计说明书 (1) 一.摘要 (2) 二.Abstract (3) 三.引言 (4) 四.机器人结构设计 (4) 四.1 整体结构设计理念 (4) 四.2 整体结构设计 (5) 四.3 垃圾收集装置设计 (6) 四.4 垃圾辅助收集装置设计 (7) 五.船重和排水量的计算 (7) 六.最大吃水深度的计算 (8) 七.动力装置设计 (8) 八.硬件设计 (10) 八.1系统总体设计 (10) 八.2电源模块 (11) 八.3电机驱动模块 (11) 八.4无线传输模块 (12) 八.5继电器模块 (12) 八.6主程序设计 (13) 九.影像收集系统设计 (13) 十.工作参数,待机和工作时长 (14) 十一. 垃圾收集特性及参数 (14) 十二.外观特性 (15) 十三. 控制方式 (15) 十四. 成本报告 (15) 十六. 市场分析 (19) 十六.1 市场推广 (19) 十六.2 盈利模式 (20) 结束语 (20) 参考文献: (20) 一.摘要 本文为解决现如今小型封闭水面垃圾清理耗费人力物力等问题,设计制作了一款由人工辅助远程遥控进行水面垃圾清理的机器人。水面垃圾打捞船针对水面环境污染的问题,主要致力于中小型湖泊河流等水域的固体垃圾清理,如塑料袋、饮料瓶,树枝树叶以及其它易清理的水面垃圾。实现水面垃圾清理的机械化与自动化,整个打捞过程无需人工直接参与,安全性非常好,效率大约是人工打捞的几十倍,水面越大、距离越远效果越显著。本文主要对水面垃圾自动打捞船进行了船体结构、动力装置、打捞及传输装置、垃圾存储装置以及其他零部件的设计、计算及校核等。分析了水面垃圾自动打捞船需要实现的功能要求,

java虚拟机详解 免费

深入理解JVM 1 Java技术与Java虚拟机 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 图1 Java四个方面的关系 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件)。最后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。从上图也可以看出Java平台由Java虚拟机和Java应用程序接口搭建,Java 语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API,利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。 那么到底什么是Java虚拟机(JVM)呢?通常我们谈论JVM时,我们的意思可能是: 1. 对JVM规范的的比较抽象的说明; 2. 对JVM的具体实现; 3. 在程序运行期间所生成的一个JVM实例。 对JVM规范的的抽象说明是一些概念的集合,它们已经在书《The Java Virtual Machine Specification》(《Java虚拟机规范》)中被详细地描述了;对JVM的具体实现要么是软件,要么是软件和硬件的组合,它已经被许多生产厂商所实现,并存在于多种平台之上;运行Java程序的任务由JVM的运行期实例单个承担。在本文中我们所讨论的Java虚拟机(JVM)主要针对第三种情况而言。它可以被看成一个想象中的机器,在实际的计算机上通过软件模拟来实现,有自己想象中的硬件,如处理器、堆栈、寄存器等,还有自己相应的指令系统。 JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。 2 Java虚拟机的体系结构 刚才已经提到,JVM可以由不同的厂商来实现。由于厂商的不同必然导致JVM在实现上的一些不同,然而JVM还是可以实现跨平台的特性,这就要归功于设计JVM时的体系结构了。 我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统、存储区域、数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现JVM时它内部的体系结构,更重要的是提供了一种方式,用于严格定义实现时的外部行为。每个JVM都有两种机制,一个是装载具有合适名称的类(类或是接口),叫做类装载子系统;另外的一个负责执行包含在已装载的类或接口中的指令,叫做运行引擎。每个JVM又包括方法区、堆、Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:

java内存泄露定位与分析

使用IBM 性能分析工具解决生产环境中的性能问题(javacore) 上一篇 / 下一篇 2012-06-01 14:14:01 / 个人分类:javacore 查看( 655 ) / 评论( 0 ) / 评分( 0 / 0 ) https://www.doczj.com/doc/df6643798.html,/developerworks/cn/java/j-lo-javacore/index.html 序言 企业级应用系统软件通常有着对并发数和响应时间的要求,这就要求大量的用户能在高响应时间内完成业务操作。这两个性能指标往往 决定着一个应用系统软件能否成功上线,而这也决定了一个项目最终能否验收成功,能否得到客户认同,能否继续在一个行业发展壮大 下去。由此可见性能对于一个应用系统的重要性,当然这似乎也成了软件行业的不可言说的痛——绝大多数的应用系统在上线之前, 项目组成员都要经历一个脱胎换骨的过程。 生产环境的建立包含众多方面,如存储规划、操作系统参数调整、数据库调优、应用系统调优等等。这几方面互相影响,只有经过不断 的调整优化,才能达到资源的最大利用率,满足客户对系统吞吐量和响应时间的要求。在无数次的实践经验中,很多软件专家能够达成 一致的是:应用系统本身的优化是至关重要的,否则即使有再大的内存,也会被消耗殆尽,尤其是产生OOM(Out Of Memory)的错 误的时候,它会贪婪地吃掉你的内存空间,直到系统宕机。 内存泄露—难啃的骨头 产生OOM 的原因有很多种,大体上可以简单地分为两种情况,一种就是物理内存确实有限,发生这种情况时,我们很容易找到原因,但是它一般不会发生在实际的生产环境中。因为生产环境往往有足以满足应用系统要求的配置,这在项目最初就是根据系统要求进行购 置的。 另外一种引起OOM 的原因就是应用系统本身对资源的的不恰当使用、配置,引起内存使用持续增加,最终导致JVM Heap Memory 被耗尽,如没有正确释放JDBC 的Connection Pool 中的对象,使用Cache 时没有限制Cache 的大小等等。本文并不针对各种情 况做讨论,而是以一个项目案例为背景,探索解决这类问题的方式方法,并总结一些最佳实践,供广大开发工程师借鉴参考。 项目背景介绍 项目背景: 1. 内网用户500 人,需要同时在线进行业务操作(中午休息一小时,晚6 点下班)。 2. 生产环境采用传统的主从式,未做Cluster ,提供HA 高可用性。 3. 服务器为AIX P570,8U,16G,但是只有一半的资源,即4U,8G 供新系统使用。 项目三月初上线,此前笔者与架构师曾去客户现场简单部署过一两次,主要是软件的安装,应用的部署,测一下应用是不是能够跑起来,算作是上线前的准备工作。应用上线(试运行)当天,项目组全体入住客户现场,看着用户登录数不断攀升,大家心里都没有底,高峰 时候到了440,系统开始有点反应变慢,不过还是扛下来了,最后归结为目前的资源有限,等把另一半资源划过来,就肯定没问题了。(须知增加资源,调优的工作大部分都要重新做一遍,系统级、数据库级等等,这也是后面为什么建议如果资源可用,最好一步到位的

水面垃圾智能收集装置

华北水利水电大学 大学生创新训练项目研究报告 项目名称:水面垃圾智能联合收集装置 项目负责人:沈杰 项目所属学院:机械学院 指导教师:

一、研究目标 传统的清洁方式是人工打捞清理,这种方式效率低且劳动强度大,适用于各种水域范围。随着科技的进步与社会的发展,人工打捞清理的效率低下和劳动强度大的缺点越来越突出了,随后出些了自动垃圾打捞船。自动打捞船对漂浮废物可自动打捞,也就是在船只航行的过程中依托水流的力气将打捞的树枝、水生植物、塑料袋等漂浮废物送入船舱内,可快速的大量清理废物,缩短保洁时刻。比起人工打捞有显着的优势,节省人力,降低劳动强度。但是为了保证清洁效率这些船设计的都很大,适用于大中型水域环境,无法使用于人们日常生活总经常接触到的小型水域环境。我们的项目为解决目前城市河道及风景区水域及小流域水面垃圾收集的问题,本项目拟设计一款小型全自动的水面垃圾收集装置,采用视觉传输技术,自动控制技术,特殊的结构方案等,将垃圾识别,收集,实现垃圾打捞的智能化、一体化、高效化,从而真正实现智能化作业。 二、研究过程 本次设计想要设计出一套水面垃圾自动清洁船控制系统,最终欲实现的主要任务目标有: (1)小船的基本航行功能,包括前进、后退、停止、加减速等; (2)识别水面垃圾并能进行回收。 整个系统设计由船体及推进装置、主控制芯片、电机和电机驱动电路、供电电源以及图像识别传感器等构成。 1.船体及推进装置 船体的构造与设计直接决定小船能否安全运行以及运行是否顺畅,推进装置的选择与设计将影响小船的运行效率以及安全性、稳定性等。为了保证小船能够安全、稳定、高效地在水面行驶,我们必须对智能小船的外型构造以及推动装置进行合理的选择与设计,保证各个组成部分能够相互配合。 船体应按空间大小,运行稳定,坚固性等要求来设计,我们使用过纯3D打印船体(重量小),雪弗板拼装船体(空间大,重量大),DIY塑料船体(重量小,使用方便)。 2.主要控制系统 主控系统是实现智能船无线控制的中枢,主控系统的工作正常与否直

JAVA虚拟机性能参数调优指导书

Java虚拟机性能参数调优指导书 (仅供内部使用)

目录 1概述 (5) 2JAVA虚拟机运行机制概览 (5) 2.1运行时分析 (5) 2.2垃圾收集和线程同步 (7) 3JAVA虚拟机参数分类说明 (8) 3.1Java虚拟机标准参数 (8) 3.2Java虚拟机扩展参数 (10) 4JAVA应用性能测试调优经验总结 (13) 4.1GC调优参数的使用 (13) 4.2JIT调优参数的使用 (14) 4.3Java线程调优参数的使用 (14) 5结束语 (15) 6参考文献 (15)

表目录 表1 JVM 标准参数集 (10) 表2 JVM 扩展参数集 (10) 表3 JVM GC/Hotspot相关参数集 (12) 表4 JVM 性能统计参数集 (13)

错误!未找到引用源。 关键词:Java、垃圾收集、虚拟机、即时编译 摘要:随着JAVA在应用系统级的项目开发中的使用越来越广泛,虚拟机、垃圾收集、热点编译、J2EE等新技术层出不穷,JAVA作为系统级开发的一个选择的优势也越来越明显,在此同时 其不能完全编译、垃圾收集等与生俱有的特征也使得JAVA备受争议的“慢”得到更多的关 注。本文通过对JAVA虚拟机的运行机理的分析,以及JAVA虚拟机参数使用说明等描述,试 图使读者能够更好的运行他的基于JAVA的应用系统,以最小的代价换取最大的收益。 缩略语清单: 缩略语英文全名中文解释 JAVA SUN公司发明的一种语言 JVM Java Virtual Machine JAVA虚拟机 GC Garbage Collection 垃圾收集 HotSpot Java虚拟机内部的一种热点编译技术 JIT Just-In-Time 即时编译技术

Elasticsearch Java虚拟机配置详解

JVM参数Elasticsearch默认值Environment变量 -Xms 256m ES_MIN_MEM -Xmx 1g ES_MAX_MEM -Xms and -Xmx ES_HEAP_SIZE -Xmn ES_HEAP_NEWSIZE -XX:MaxDirectMemorySize ES_DIRECT_SIZE -Xss 256k -XX:UseParNewGC + -XX:UseConcMarkSweepGC + -XX:CMSInitiatingOccupancyFraction 75 -XX:UseCMSInitiatingOccupancyOnly + -XX:UseCondCardMark (commented out) 首先你注意到的是,Elasticsearch预留了256M到1GB的堆内存。 这个设置适用于开发和演示环境。开发人员只需要简单的解压发行包,再执 行./bin/elasticsearch -f就完成了Elasticsearch的安装。当然这点对于开发来说非常棒,并且在很多场景下都能工作,但是当你需要更多内存来降低Elasticsearch负载的时候就不行了,你需要比2GB RAM更多的可用内存。

ES_MIN_MEM/ES_MAX_MEM是控制堆大小的配置。新的ES_HEAP_SIZE变量是一个更为便利的选择,因为将堆的初始大小和最大值设为相同。也推荐在分配堆内存时尽可能不要用内存的碎片。内存碎片对于性能优化来说非常不利。 ES_HEAP_NEWSIZE是可选参数,它控制堆的子集大小,也就是新生代的大小。 ES_DIRECT_SIZE控制本机直接内存大小,即JVM管理NIO框架中使用的数据区域大小。本机直接内存可以被映射到虚拟地址空间上,这样在64位的机器上更高效,因为可以规避文件系统缓冲。Elasticsearch对本机直接内存没有限制(可能导致OOM)。 由于历史原因Java虚拟机有多个垃圾收集器。可以通过以下的JVM参数组合启用: JVM parameter Garbage collector -XX:+UseSerialGC serial collector -XX:+UseParallelGC parallel collector -XX:+UseParallelOldGC Parallel compacting collector -XX:+UseConcMarkSweepGC Concurrent-Mark-Sweep (CMS) collector -XX:+UseG1GC Garbage-First collector (G1) UseParNewGC和UseConcMarkSweepGC组合启用垃圾收集器的并发多线程模式。UseConcMarkSweepGC自动选择UseParNewGC模式并禁用串行收集器(Serial collector)。在Java6中这是默认行为。 CMSInitiatingOccupancyFraction提炼了一种CMS(Concurrent-Mark-Sweep)垃圾收集设置;它将旧生代触发垃圾收集的阀值设为75.旧生代的大小是堆大小减去新生代大小。这告诉JVM当堆内容达到75%时启用垃圾收集。这是个估计的值,因为越小的堆可能需要越早启动GC。 UseCondCardMark将在垃圾收集器的card table使用时,在marking之前进行额外的判断,避免冗余的store操作。UseCondCardMark不影响Garbage-First收集器。强烈推荐在高并发场景下配置这个参数(规避card table marking技术在高并发场景下的降低吞吐量的负面作用)。在ElasticSearch中,这个参数是被注释掉的。 有些配置可以参考诸如Apache Cassandra项目,他们在JVM上有类似的需求。 总而言之,ElastciSearch配置上推荐: 1. 不采用自动的堆内存配置,将堆大小默认最大值设为1GB 2.调整触发垃圾收集的阀值,比如将gc设为75%堆大小的时候触发,这样不会影响性能。 3.禁用Java7默认的G1收集器,前提是你的ElasticSearch跑在Java7u4以上的版本上。JVM进程的内存结果 JVM内存由几部分组成: Java代码本身:包括内部代码、数据、接口,调试和监控代理或者字节码指令 非堆内存:用于加载类 栈内存:用于为每个线程存储本地变量和操作数

深入理解Java虚拟机笔记(带目录)

目录 1.虚拟机内存结构 (1) 2.对象在内存中的布局 (3) 3.判断对象是否死亡 (4) 4.引用的4中情况 (4) 5.垃圾收集算法 (5) 6.HotSpot虚拟机算法实现 (6) 7.如何在GC发生时让所有线程都要附近的安全点停下 (6) 8.垃圾收集器 (7) 9.GC日志 (9) 10.内存分配 (10) 11.Class类文件的结构 (10) 12.类的生命周期 (13) 13.类加载器 (15) 14.运行时栈帧的结构 (16) 15. 方法调用 (18) 16. 分派 (19) 17.虚方法表 (19) 18.Java内存模型(JMM) (19) 19.内存间的交互 (20) 20.volatile变量 (20) 21.原子性 (21) 22.可见性 (22) 23.有序性 (22) 24.先行发生原则 (22) 25.Java线程调度 (23) 26.线程的状态 (24) 27.线程安全 (25) 28.线程安全的实现方法 (26) 29.锁优化 (27) 30.编译优化技术 (29) 1.虚拟机内存结构 线程私有:虚拟机栈,本地方法栈,程序计数器 线程共享:堆,方法区(包括运行时常量池)

1.1程序计数器 当前程序锁执行的字节码行号指示器,记录下一条需要执行的 指令。 1.2虚拟机栈 生命周期与线程相同,每个方法在执行时都会创建一个栈帧。 方法执行的过程,就是栈帧入栈到出栈的过程。 栈帧用于存放局部变量表,操作数栈,动态链接,方法出口等 信息。 局部变量表存放了编译期可知的基本数据类型和对象引用。1.3 本地方法栈 为虚拟机使用到的Native方法服务。 目前HotSpot虚拟机将本地方法栈和虚拟机栈合二为一。 1.4堆 存放对象实例,所有线程共享。 1.5 方法区(永久代) 存放被虚拟机加载的类信息,常量,静态变量,即时编译器编 译后的代码等。

java内存空间详解

硬盘 heap stack Data code 内存 程序 操作系统代码 程序代码 New ,在堆里面为属性分配空间,初始化(String 默认值为null ) 声明的时候非配空间,初始值为null (局部变量,方法参数) 全局变量 存放程序所需要的代码 类变量,全局字符串,常量存放在数据段

Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java 在内存分配方面的知识。一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 ◆堆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量

◆非RAM存储:硬盘等永久存储空间 Java内存分配中的栈 在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。 Java内存分配中的堆 堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。 在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。 引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是Java 比较占内存的原因。 实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针! 常量池(constant pool) 常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如: ◆类和接口的全限定名; ◆字段的名称和描述符; ◆方法和名称和描述符。 虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和floating point常量)和对其他类型,字段和

水面垃圾自动打捞船的设计(毕业设计)

摘要 水面垃圾自动打捞船针对水面环境污染的问题,主要致力于中小型湖泊河流等水域的固体垃圾清理,如塑料袋、饮料瓶,树枝树叶以及其它易清理的水面垃圾。实现水面垃圾清理的机械化与自动化,整个打捞过程无需人工参与,安全性非常好,效率大约是人工打捞的几百倍,水面越大、风浪越大效果越显著。 本文主要对水面垃圾自动打捞船进行了船体结构、动力装置、打捞及传输装置、垃圾存储装置以及其他零部件的设计、计算及校核等。分析了水面垃圾自动打捞船需要实现的功能要求,在实际环境背景下,研究了水面垃圾自动打捞船的系统构成及功能、各零部件的的设计方法以及系统的实现方式。 此设计除了动力装置与其他船类大体相似,实现打捞和传输的装置以及垃圾存储装置都有一定的创新性设计。采用链齿轮与链条的传动带动传输带的形式,以及船体前方挡板引导装置和叶轮的设计都使得水面垃圾的收集更加有效率。此外,垃圾存储装置采用的是三个可替换式的存储箱,其底部设计为多孔式,使得水面垃圾的收集更加方便,可执行性有所加强。 本文还附有部分水面垃圾收集船的结构图,装配图,零件图,以便详细的说明设计过程。 关键字:水面垃圾自动打捞船环境保护结构设计

Abstract An autonomous ship for cleaning the garbage floating on a lake is designed for the water pollution problems,mainly to solid waste on small and medium sized lakes , rivers and other waters,such as plastic bags,bottles,leaves,twigs,and other surface trash which is easy to clean. To achieve clean the water garbage mechanized and automatically , the entire salvage process without human intervention , security is very good , efficiency is about hundreds of times than artificial salvage. The greater the surface and more significant storms, the greater the effect is. This essay focuses on the design,computing and checking of hull structure , power plant, salvage and transport equipment,garbage storage devices and other components of the an autonomous ship . In the case of the understanding of the results of the design required to achieve the functional requirements, as well as the actual environmental background to study the design of the structure and function of the water garbage sweeper system . This power plant design in addition to the other boat classes are generally similar . And garbage storage devices, the device to achieve salvage and transport have some innovative designs.Form of the sprockets and the chain transmission is driven by a transmission belt,and the hull in front of the baffle means and the guide surface of the impeller are designed so that garbage collection more efficient.In addition, garbage storage device uses three replaceable storage tank , the bottom is designed to porous surface garbage collection more convenient, enforceability has been strengthened . This article is also append the structure and assembly drawings , parts diagram of the autonomous ship for cleaning the garbage floating on a lake for a detailed description of the design process. Keywords: The water waste;Automatic cleaning ship;environmental protection; Structural Design

深入理解java虚拟机

深入理解java虚拟机 (一)虚拟机内存划分 Java虚拟机在执行Java程序时,会把它管理的内存划分为若干个不同的数据区。这些区域有不同的特性,起不同的作用。它们有各自的创建时间,销毁时间。有的区域随着进程的启动而创建,随着进程结束而销毁,有的则始终贯穿虚拟机整个生命周期。 Java虚拟机运行时内存区域主要分为七部分,分别是:程序计数器,Java虚拟机栈,本地方法栈,方法区,Java堆,运行时常量池,直接内存。 如上图所示(图片来源于网络): 蓝色区域包裹的部分为运行时几个数据区域: 白色的部分为线程私有的,既随着线程的启动而创建。每个线程都拥有各自的一份内存区域。它们是:JAVA栈(JAVA STACK),本地方法栈(NATIVE METHOD STACK),和程序计数器(PROGRAM COUNTER REGISTER)。 黄色部分是线程共享的,所有的线程共享该区域的内容。他们是: 方法区(METHOD AREA),堆(HEAP)。 我们分别来介绍这些区域。 (1)程序计数器(program counter register)

学过计算机组成原理的都知道计算机处理器中的程序计数器。当处理器执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。 处理器的程序计数器是指寄存器,而java程序计数器是指一小块内存空间。java代码编译字节码之后,虚拟机会一行一行的解释字节码,并翻印成本地代码。这个程序计数器盛放的就是当前线程所执行字节码的行号的指示器。在虚拟机概念模型中,字节码解释器工作室就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理等都依赖于它。 Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,因此为了线程切换后还能恢复执行位置,每条线程都需要一个独立的程序计数器。 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Java Native方法,这个计数器值为空。 而且程序计数器是Java虚拟机中没有规定任何OutOfMemoryError的区域。 (2)虚拟机栈 Java虚拟机栈(VM Stack)也是线程私有的,因此它的生命周期也和线程相同。它存放的是Java方法执行时的数据,既描述的是Java方法执行的内存模型:每个方法开始执行的时候,都会创建一个栈帧(Stack Frame)用于储存局部变量表、栈操作数、动态链接、方法出口等信息。每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出栈的过程。经常有人把Java内存分为堆内存和栈内存,这种是比较粗糙的分法,很大原因是大多数程序‘猿’最关注的,与对象内存分配最密切的区域就是堆和栈。局部变量表存放的是编译器可知的各种基本数据类型(boolean 、byte、int、long、char、short、float、double)、对象引用(reference类型)和returnAddress类型(它指向了一条字节码指令的地址)。其中64bit长度的long和double会占用两个局部变量空间(Slot),其余的数据类型只占用一个。局部变量表所需的内存空间是在编译时期确定的,在方法运行期间不会改变局部变量表的大小。在Java虚拟机规范中,对这部分区域规定了两种异常:1、当一个线程的栈深度大于虚拟机所允许的深度的时候,将会抛出StackOverflowError异常; 2、如果当创建一个新的线程时无法申请到足够的内存,则会抛出OutOfMemeryError异常。 (3)本地方法栈 本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是十分相似的,他们之间的区别不过是虚拟机栈为Java方法字节码服务,而本地方法栈则为Native方法服务。在虚拟机规范中对本地方法使用的语言和使用方法与数据结构没有强制规定,因此具体的虚拟机可

相关主题
文本预览
相关文档 最新文档