1700452287
1700452288
java-Xmx1536m-Xms1024m
1700452289
1700452290
(2)调整堆内存中各分区的比例
1700452291
1700452292
JVM的堆内存包括三部分:新生区(Young Generation Space)、养老区(Tenure generation space)、永久存储区(Permanent Space),其中新生成的对象都在新生区,它又分为伊甸区(Eden Space)、幸存0区(Survivor 0 Space)和幸存1区(Survivor 1 Space),当在程序中使用了new关键字时,首先在伊甸区生成该对象,如果伊甸区满了,则用垃圾回收器先进行回收,然后把剩余的对象移动到幸存区(0区或1区),可如果幸存区也满了呢?垃圾回收器会再回收一次,然后再把剩余的对象移动到养老区,那要是养老区也满了呢?此时就会触发Full GC(这是一个非常危险的动作,JVM会停止所有的执行,所有系统资源都会让位给垃圾回收器),会对所有的对象过滤一遍,检查是否有可以回收的对象,如果还是没有的话,就抛出OutOfMemoryError错误,系统不干了!
1700452293
1700452294
清楚了这个原理(若还是不清楚,请看看《JVM Specification》),那我们就可以思考一下如何提升性能了:若扩大新生区,势必会减少养老区,这就可能产生不稳定的情况,一般情况下,新生区和养老区的比例为1:3左右,设置命令如下:
1700452295
1700452296
java-XX:NewSize=32m-XX:MaxNewSize=640m-XX:MaxPermSize=1280m-XX:NewRatio=5
1700452297
1700452298
该配置指定新生代初始化为32MB(也就是新生区最小内存为32M),最大不超过640MB,养老区最大不超过1280MB,新生区和养老区的比例为1:5。
1700452299
1700452300
(3)变更GC的垃圾回收策略
1700452301
1700452302
Java程序性能的最大障碍就是垃圾回收,我们不知道它何时会发生,也不知道它会执行多长时间,但是我们可以想办法改变它对系统的影响,比如启用并行垃圾回收、规定并行回收的线程数量等,命令格式如下:
1700452303
1700452304
java-XX:+UseParallelGC-XX:ParallelGCThreads=20
1700452305
1700452306
这里启用了并行垃圾收集机制,并且定义了20个收集线程(默认的收集线程等于CPU的数量),这对多CPU的系统是非常有帮助的,可以大大减少垃圾回收对系统的影响,提高系统性能。
1700452307
1700452308
当然,垃圾回收的策略还有很多属性可以修改,比如UseSerialGC(启用串行GC,默认值)、ScavengeBeforeFullGC(新生代GC优先于Full GC执行)、UseConcMarkSweepGC(对老生代采用并发标记交换算法进行GC)等,这些参数需要在系统中逐步调试。
1700452309
1700452310
(4)更换JVM
1700452311
1700452312
如果所有的JVM优化都不见效,那只有使用最后一招了:更换JVM,目前市面上比较流行的JVM有三个产品:Java HotSpot VM、Oracle JRockit JVM、IBM JVM,其中HotSpot是我们经常使用的,稳定性、可靠性都不错;JRockit则以效率著称,性能是它的优势,但在决定使用该JVM之前一定要做好全面的系统测试,它的某些行为可能会在JRockit上产生Bug;IBM JVM也比较稳定,而且它在AIX系统上的表现要远远好于其他操作系统。
1700452313
1700452314
JVM的优化不能像程序优化一样,找到Bug就可以立刻解决,JVM的优化一定是要循序渐进的,参数设置不可激进,特别是需要优化多个参数时,一定要逐步实施,确保每个优化步骤都达到了预期目标,否则会对整个系统的稳定性产生较大的风险。需要提醒的是以上带有“-XX”的JVM参数可能是不健壮的,SUN也不推荐使用,可能后续会在没有通知的情况下就不再支持它了,但是它又非常好用,这需要在系统升级、迁移时慎重考虑。
1700452315
1700452316
1700452317
1700452318
1700452320
编写高质量代码:改善Java程序的151个建议 建议138:性能是个大“咕咚”
1700452321
1700452322
有一部动画片叫《咕咚来了》,其大致剧情是:三只小兔在湖边玩耍,忽然湖中传来“咕咚”一声,这奇怪的声音把小兔们吓了一大跳。小兔们刚想去看个究竟,又听到“咕咚”一声,这可把小兔们吓坏了,“快跑,咕咚来了,快逃呀!”小兔们转身就跑。
1700452323
1700452324
狐狸正同小鸟跳舞,与跑来的兔子碰了个满怀。狐狸一听“咕咚来了!”也紧张起来,跟着就跑。它们又惊醒了睡觉的小熊和树上的小猴,小熊和小猴也不问青红皂白,跟着它们跑起来,于是一路上跟着跑的动物越来越多,大象、河马、老虎、野猪……
1700452325
1700452326
岸上这阵骚乱,让湖中的青蛙感到十分惊讶,它拦住了这群吓蒙了的伙伴们,问出了什么事,大家七嘴八舌地形容“咕咚”是个多么可怕的怪物。青蛙问:“谁见到了?”大家互相推诿,谁也没有亲眼看见,于是决定回去看看明白。
1700452327
1700452328
回到湖边,又听见“咕咚”一声,仔细一看,原来是木瓜掉进水里发出的声音,众动物不禁大笑起来。
1700452329
1700452330
这寓言故事好笑吗?很好笑,但是要是发生在我们自己身上就不那么好笑了,比如说,某些Javaer一直在质疑Java系统的性能,于是我们自己也跟着怀疑Java的性能—这就是发生在我们身边的真实“咕咚”,Java系统的性能问题本就是子虚乌有的事情,是我们自己吓唬自己,其实,我们可以从四个方面分析该问题:
1700452331
1700452332
(1)没有慢的系统,只有不满足业务的系统
1700452333
1700452334
不管是使用C开发还是Java开发的项目,最终都会有一个产品诞生,或服务于大众(如网站),或服务于企业(企业级应用),谁来决定一个系统的快慢呢?不是计算机,它只会使用毫秒、纳秒去记录时间但不会做判断,它可以计算出一个交易执行了多长时间,但它不能决定这个时间是长还是短,那谁去判断呢?是人,准确地说是使用者,即使是开发人员自己根据日志记录的时间来判断系统是慢了还是快了,那也还是以使用者的身份来判断的,对一个系统毫无了解的人员是无法判断出一个系统的快慢的。
1700452335
1700452336
例如一个做统计的业务人员去看计费系统,即使响应需要N秒的时间,统计人员也会觉得非常快了,那是因为统计系统的结果经常是按照小时、天来计算的。再比如即时通信系统,有1秒内的延迟是可以接受的(发送者发出消息到接受者接收消息的时间间隔为1秒),但是语音通信系统若有1秒的延迟就是不可接受的了;发送邮件N分钟后才收到,这是可以容忍的,但是对于同城银行内转账来说,这个时间就是不可容忍的,必须在秒级完成。不同的系统所要求的性能不同,因此只要一个系统达到业务要求就可以认为它足够快,我们不要期望跨系统间的性能对比,这是毫无意义的。
[
上一页 ]
[ :1.700452287e+09 ]
[
下一页 ]