《java虚拟机(JVM)调优案例分析与MyEclipse性能调优实战.ppt》由会员分享,可在线阅读,更多相关《java虚拟机(JVM)调优案例分析与MyEclipse性能调优实战.ppt(35页珍藏版)》请在三一办公上搜索。
1、第6讲-Java虚拟机调优案例分析与MyEclipse性能调优实战,软件工程系 潘正军,主要内容大纲,案例分析实战:MyEclipse运行性能调优,本节内容引入,前面课程介绍了处理Java虚拟机内存问题的知识与工具,在处理实际项目的问题时,除了知识与工具外,经验同样是一个很重要的因素。因此本章将与读者分享几个比较有代表性的实际案例。考虑到虚拟机故障处理和调优主要面向各类服务端应用,而大部分Java程序员较少有机会直接接触生产环境的服务器,因此本章还准备了一个所有开发人员都能够进行“亲身实战”的练习,希望通过实践使读者获得故障处理和调优的经验。,一、案例分析1-高性能硬件上的程序部署策略,1.高
2、性能硬件上的程序部署策略 例如,一个15万PV(page view)/天左右的在线文档类型网站最近更换了硬件系统,新的硬件为4个CPU、16GB物理内存,操作系统为64位CentOS 5.4,Resin作为Web服务器。整个服务器暂时没有部署别的应用,所有硬件资源都可以提供给这访问量并不算太大的网站使用。管理员为了尽量利用硬件资源选用了64位的JDK 1.5,并通过-Xmx和-Xms参数将Java堆固定在12GB。使用一段时间后发现使用效果并不理想,网站经常不定期出现长时间失去响应的情况。监控服务器运行状况后发现网站失去响应是由GC停顿导致的,虚拟机运行在Server模式,默认使用吞吐量优先收
3、集器,回收12GB的堆,一次Full GC的停顿时间高达14秒。并且由于程序设计的关系,访问文档时要把文档从磁盘提取到内存中,导致内存中出现很多由文档序列化产生的大对象,这些大对象很多都进入了老年代,没有在Minor GC中清理掉。这种情况下即使有12GB的堆,内存也很快被消耗殆尽,由此导致每隔十几分钟出现十几秒的停顿,令网站开发人员和管理员感到很沮丧。,一、案例分析1-高性能硬件上的程序部署策略,在高性能硬件上部署程序,目前主要有两种方式:1.通过64位JDK来使用大内存。2.使用若干个32位虚拟机建立逻辑集群来利用硬件资源。此案例中的管理员采用了第一种部署方式。对于用户交互性强、对停顿时间
4、敏感的系统,可以给Java虚拟机分配超大堆的前提是有把握把应用程序的Full GC频率控制得足够低,至少要低到不会影响用户使用,譬如十几个小时乃至一天才出现一次Full GC,这样可以通过在深夜执行定时任务的方式触发Full GC甚至自动重启应用服务器来保持内存可用空间在一个稳定的水平。控制Full GC频率的关键是看应用中绝大多数对象能否符合“朝生夕灭”的原则,即大多数对象的生存时间不应太长,尤其是不能有成批量的、长生存时间的大对象产生,这样才能保障老年代空间的稳定。,一、案例分析1-高性能硬件上的程序部署策略,在大多数网站形式的应用里,主要对象的生存周期都应该是请求级或者页面级的,会话级和
5、全局级的长生命对象相对很少。只要代码写得合理,应当都能实现在超大堆中正常使用而没有Full GC,这样的话,使用超大堆内存时,网站响应速度才会比较有保证。除此之外,如果读者计划使用64位JDK来管理大内存,还需要考虑下面可能面临的问题:内存回收导致的长时间停顿。现阶段,64位JDK的性能测试结果普遍低于32位JDK。需要保证程序足够稳定,因为这种应用要是产生堆溢出几乎就无法产生堆转储快照(因为要产生十几GB乃至更大的Dump文件),哪怕产生了快照也几乎无法进行分析。相同程序在64位JDK消耗的内存一般比32位JDK大,这是由于指针膨胀,以及数据类型对齐补白等因素导致的。,一、案例分析2-集群间
6、同步导致的内存溢出,例如,有一个基于B/S的MIS系统,硬件为两台2个CPU、8GB内存的HP小型机,服务器是WebLogic 9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群。由于是亲合式集群,节点之间没有进行Session同步,但是有一些需求要实现部分数据在各个节点间共享。开始这些数据存放在数据库中,但由于读写频繁竞争很激烈,性能影响较大,后面使用JBossCache构建了一个全局缓存。全局缓存启用后,服务正常使用了一段较长的时间,但最近却不定期地出现了多次的内存溢出问题。,一、案例分析2-集群间同步导致的内存溢出,在内存溢出异常不出现的时候,服务内存回收状况一
7、直正常,每次内存回收后都能恢复到一个稳定的可用空间,开始怀疑是程序某些不常用的代码路径中存在内存泄漏,但管理员反映最近程序并未更新、升级过,也没有进行什么特别操作。只好让服务带着-XX:+HeapDumpOnOutOfMemoryError参数运行了一段时间。在最近一次溢出之后,管理员发回了heapdump文件,发现里面存在着大量org.jgroups.protocols.pbcast.NAKACK对象。JBossCache是基于自家的JGroups进行集群间的数据通信,JGroups使用协议栈的方式来实现收发数据包的各种所需特性自由组合,数据包接收和发送时要经过每层协议栈的up()和down
8、()方法,其中的NAKACK栈用于保障各个包的有效顺序及重发。,一、案例分析2-集群间同步导致的内存溢出,由于信息有传输失败需要重发的可能性,在确认所有注册在GMS(Group Membership Service)的节点都收到正确的信息前,发送的信息必须在内存中保留。而此MIS的服务端中有一个负责安全校验的全局Filter,每当接收到请求时,均会更新一次最后操作时间,并且将这个时间同步到所有的节点去,使得一个用户在一段时间内不能在多台机器上登录。在服务使用过程中,往往一个页面会产生数次乃至数十次的请求,因此这个过滤器导致集群各个节点之间网络交互非常频繁。当网络情况不能满足传输要求时,重发数据
9、在内存中不断堆积,很快就产生了内存溢出。,一、案例分析3-堆外内存导致的溢出错误,一、案例分析3-堆外内存导致的溢出错误,一、案例分析3-堆外内存导致的溢出错误,一、案例分析4-外部命令导致系统缓慢,一、案例分析5-服务器JVM进程崩溃,一、案例分析6和7,6.不恰当数据结构导致内存占用过大7.由Windows虚拟内存导致的长时间停顿请参考教材,二、实战:MyEclipse运行性能调优,很多Java开发人员都有这样一种观念:系统调优的工作都是针对服务端应用而言,规模越大的系统,就越需要专业的调优运维团队参与。这个观点不能说不对,上一节中笔者所列举的案例确实都是服务端运维、调优的例子,但服务端应
10、用需要调优,并不说明其他应用就不需要了,作为一个普通的Java开发人员,前面讲的各种虚拟机的原理和最佳实践方法距离我们并不遥远,开发者身边很多场景都可以使用上面这些知识。下面通过一个普通程序员日常工作中可以随时接触到的开发工具开始这次实战。,2.1 MyEclipse调优前的程序运行状态,MyEclipse初始配置:找到myeclipse.ini文件,查看原始配置,2.2 VisualVm监控MyEclipse的原始情况,2.3 VisualVm监控myeclipse结果分析,从图中可以看出,仅启动过程就有350次young gc,21次full gc。为了查看gc细节,在myeclipse.
11、ini中加入如下参数:-verbose:gc-XX:+PrintGCDetails-XX:+PrintGCDateStamps-Xloggc:D:/jvmlog/eclipse_gc.loggc的内容如下:,2.3 VisualVm监控myeclipse结果分析与调优,2.3 VisualVm监控myeclipse结果分析与调优,2.4 VisualVm监控myeclipse GC结果分析与调优,从gc日志中可以看出:(1)young区开始为960K,持续的不够,因此造成不断的young gc(2)full gc时,old区的空间增大扩容,从89312k增加到98724k,因此old区空间也不
12、够为了防止这种情况发生,加入以下参数:-Xms768m-Xmx768m-XX:NewSize=512m-XX:MaxNewSize=512m,2.4 VisualVm监控myeclipse运行结果分析与调优,此次调整后结果如下图,2.4 VisualVm监控myeclipse运行结果分析与调优,从图中可以看出,young gc没有了,但为什么还有14次full gc呢?以下是此次gc的日志:,2.4 VisualVm监控myeclipse运行结果分析与调优,从gc.log中,可以看出,是因为perm区的没有空间了,才导致的full gc,于是将perm区增大并固定大小加入以下参数:-XX:Pe
13、rmSize=96m-XX:MaxPermSize=96m此次调整后结果如下图:从图中结果可以看出,没有full gc了,而且young gc只有2次,有了一定的效果了,2.4 VisualVm监控myeclipse运行结果分析与调优,2.5 VisualVm监控myeclipse运行结果分析与调优,启动时gc的问题解决了,现在来看其他问题:,2.5 VisualVm监控myeclipse运行结果分析与调优,从图中可以看出,如果classloader加载class的时间能快些,应该也会节省些时间加入以下参数:-Xverify:none(关闭Java字节码验证,从而加快了类装入的速度),2.5
14、VisualVm监控myeclipse运行结果分析与调优,2.5 VisualVm监控myeclipse运行结果分析与调优,将上两图比较第一个:平均每个类的载入时间为,3.211/13708=0.000234242777939889s第二个:平均每个类的载入时间为,2.314/11725=0.00s可以看出,多少是有一些性能上的提高的,2.6 VisualVm监控myeclipse运行结果分析与调优,考虑到eclipse长时间运行,其他可能调节的有以下几点:(1)关闭System.gc()(2)提高eclipse中某些代码的JIT编译(3)优化垃圾收集器,以减少垃圾收集造成应用无响应的时间对于
15、(1),加入以下参数:-XX:+DisableExplicitGC对于(2),会影响启动速度,但由于eclipse是长时间运行,因此此优化是必要的:-XX:CompileThreshold=100(方法调用多少次就会被编译成本地机器码),2.6 VisualVm监控myeclipse运行结果分析与调优,2.6 VisualVm监控myeclipse运行结果分析与调优,可以看出,编译方法的数量和时间明显增加对于(3),换用CMS收集器应该比串行收集器要好,加入以下参数:-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:CMSInitiatingOccupanc
16、yFraction=80至此,调优结束,2.7 MyEclipse运行性能调优总结,总结一下myeclipse.ini文件中加入的性能调优参数如下:-verbose:gc-XX:+PrintGCDetails-XX:+PrintGCDateStamps-Xloggc:D:/jvmlog/eclipse_gc.log-Xms512m-Xmx512m-XX:NewSize=256m-XX:MaxNewSize=256m-XX:PermSize=96m-XX:MaxPermSize=96m-XX:+DisableExplicitGC-XX:CompileThreshold=100-Xverify:none-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:CMSInitiatingOccupancyFraction=80,态度决定命运,专注成就人生!谢谢!,