调优案例分析与实战

调优案例分析与实战

1 高性能硬件上的程序部署策略

2 集群间同步导致的内存溢出

3 堆外内存导致的溢出错误

4 外部命令导致系统缓慢

5 服务器JVM进程崩溃

3 实战:Eclipse运行速度调优

1.Eclipse:由于安装的插件比较大(如Klocwork、ClearCase LT等)、代码也很多,启动Eclipse直到所有项目编译完成需要四五分钟

配置文件eclipse. ini;代码清单5-4eclipse启动耗时统计;涉及测试方法以及数据分析;

2.升级JDK1.6的性能变化及兼容问题

JDK 1.5、1.6、1.7三个版本做的性能评测;

eclipse的buglist网站:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZBPf3abJ-1578644897662)(C:\Users\zhangli\AppData\Roaming\Typora\typora-user-images\image-20191225101322417.png)]

jdk1.5指定了最大永久代容量XX:MaxPermSize=256M,jdk1.6没有,使用默认64MB;

虚拟机的参数传递:

使用JDK 1.5时之所以有永久代容量这个参数,是因为在eclipse.ini中存在“–launcher.XXMaxPermSize256M”这项设置,当launcher—Windows下的可执行程序eclipse.exe检测到是Eclipse运行在Sun公司的虚拟机上的话,就会把参数值转化为-XX:MaxPermSize传递给虚拟机进程,因为三大商用虚拟机中只有Sun系列的虚拟机才有永久代的概念,即只有HotSpot虚拟机需要设置这个参数,JRockit虚拟机和IBM J9虚拟机都不需要设置

2010年4月10日,Oracle正式完成了对Sun的收购,之后的版本都需要在eclipseini中指定永久代参数;

3 编译时间和类加载时间的优化

sun jdk1.6性能白皮书网址:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8bP1fcy-1578644897663)(C:\Users\zhangli\AppData\Roaming\Typora\typora-user-images\image-20191225102029528.png)]

代码清单5-7 JDK1.5和1.6中的类加载时间对比

(多次试验后,发现在笔者机器上的两个JDK进行类加载时,字节码验证部分的耗时差距尤其严重)通过参数-Xverify:none禁止掉字节码验证;

类加载时间,编译时间(Compile Time)和垃圾收集时间(GC Time)

Java语言为了实现跨平台的特性,Java代码编译出来后形成的Class文件中储存的是字节码(ByteCode),虚拟机通过解释方式执行字节码命令,比起C/C++编译成本地二进制代码来说,速度要慢不少

编译时间是指虚拟机的JIT编译器(Just In Time Compiler)编译热点代码(Hot SpotCode)的耗时,

如果一段Java方法被调用的次数到达一定程度,就会被判定为热代码,从而交给JIT编译器即时编译为本地代码,以提高运行速度(这就是HotSpot虚拟机名字的由来)

Java运行期编译最大的缺点就是编译需要消耗程序正常的运行时间,也就是上面所说的“编译时间”

与解释执行相对应的另一方面,虚拟机还有力度更强的编译器:

当虚拟机运行在-client模式的时候,使用的是一个代号为C1的轻量级编译器,另外还有一个代号为C2的相对重量级的编译器,它能提供更多的优化措施

如果使用-server模式的虚拟机启动Eclipse将会用到C2编译器,这时从VisualGC可以看到启动过程中虚拟机使用了超过15秒的时间去进行代码编译。如果读者的工作习惯是长时间不关闭Eclipse的话,C2编译器所消耗的额外编译时间最终还是会在运行速度的提升之中赚回来

4 调整内存设置控制垃圾收集频率

问题:在Eclipse启动的原始数据样本中,短短15秒类共发生了19次Full GC和378次Minor GC,一共397次GC,共造成了超过4秒的停顿

解决1:新生代中的Minor GC,虽然GC的总时间只有不到1秒,但却发生了378次之多。从VisualGC的线程监视中看到Eclipse启动期间一共发起了超过70个线程,同时在运行的线程数超过25个,每当发生一次垃圾收集的动作,所有的用户线程[插图]都必须跑到最近的一个安全点(SafePoint),然后挂起线程等待垃圾回收。这样过于频繁的GC就会导致很多没有必要的安全点检测、线程挂起及恢复操作

方法:使用-Xmn参数调整新生代的大小

解决2:19次Full GC

从GC日志中分析一下这些Full GC是如何产生的,每发生一次Full GC都伴随着一次老年代空间扩容,10次GC以后老年代容量从起始的1536KB扩大到46828KB,当15秒后Eclipse启动完成时,老年代容量扩大到了103428KB,代码编译开始后,老年代容量达到顶峰473MB,整个Java堆达到最大容量512MB

结论:得出结论:Eclipse启动时Full GC大多数是由于老年代容量扩展而导致的,由永久代空间扩展而导致的也有一部分

方法:把-Xms和-XX:PermSize参数值分别设置为-Xmx和-XX:PermSizeMax参数值,强制虚拟机在启动的时候就把老年代和永久代的容量固定下来,避免运行时自动扩展

问题3从Old Gen曲线上看,永久代直接固定在384MB,而内存使用量只有66MB,并且一直很平滑,完全不应该发生FullGC才对,那4次Full GC是怎么来的?使用jstat -gccause查询一下最近一次GC的原因

愿意:System.gc()显式触发的GC

方法:在eclipse.ini中加入参数-XX:+DisableExplicitGC屏蔽掉System.gc()

5 选择收集器降低延迟

针对代码编译时间;

使用习惯:在做全量编译或清理动作的时候,使用“Run in Backgroup”功能一边编译一边继续工作

解决方案:容易想到CMS是最符合这类场景的收集器。因此尝试在eclipse.ini中再加入两个参数-XX:+UseConcMarkSweepGC和-XX:+UseParNewGC(ParNew收集器是使用CMS收集器后的默认新生代收集器,写上仅是为了使得配置更加清晰)

场景:CMS默认老年代使用了68%就进行收集,所以Full GC次数上升到了6次,

解决方案:为了避免总体吞吐量下降得太厉害,使用-XX:CMSInitiatingOccupancyFraction = 85将GC临界值提升到85%

此外还有的服务器端调优包括:数据库、资源池、磁盘I/O等

upancyFraction = 85将GC临界值提升到85%

此外还有的服务器端调优包括:数据库、资源池、磁盘I/O等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值