无障碍 关怀版

Jvm优化指南、简介、参数、编译器

Jvm简介

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

Java Hotspot vm参数配置

-client -server -classpath / -cp

-verbose :class 输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。

-verbose:gc 输出每次GC的相关情况

-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

jvm参数

Heapsize 堆栈大小

-Xms 定义最小值 -Xmx 定义最大值 建议设置相同,防止垃圾收集器在最小、最大之间收缩堆而产生额外开销。

GC垃圾回收--新生代New配置

-XX:newSize

-XX:MaxNewSize

建议设置相同,防止年轻代的堆收缩。

GC垃圾回收—旧生代Old配置 -XX:NewRadio=2表示新生代:老年代 = 1:2

Jit编译器:c1/c2

在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,但大多数情况下我们简称为C1编译器和C2编译器。开发人员可以通过如下命令显式指定Java虚拟机在运行时到底使用哪一种即时编译器,如下所示:

C1编译器会对字节码进行简单和可靠的优化,以达到更快的编译速度;而C2编译器会启动一些编译耗时更长的优化,以获取更好的编译质量。

垃圾回收

Java的堆内存模型

新生代(Young generation)

绝大多数被新建的对象会分配到这里,由于大部分对象在创建后会很快变得不可达,所以很多对象被创建在新生代,然后消失,对象消失的过程称为”minor GC”

新生代存在1个eden区和2个survivor区,新对象会首先分配到eden区,当然如果对象过大会直接分配到老年代,在gc中,eden中的对象会被移动到survivor中,直到对象满足一定年纪(熬过gc的次数),会被移动到老年代

可以设置新生代和老年代的相对大小,这种方式的优点是新生代的大小随着堆内存的动态扩展,设置方式为-XX:NewRatio,例如-XX:NewRatio=8代表老年代/新生代为8/1,老年代占堆内存的7/8,新生代占1/8

老年代(Old generation)

对象没有变的不可达,在新生代中存活下来的对象会被拷贝到这里,其占用的空间比新生代多,因为其占用空间大,所以发生在老年代上的gc比新生代少,对象从老年代消失的过程称之为”major GC”或者”full GC”

永久代(permanent generation)

像一些类级的层次信息,方法数据和方法信息,运行时常量(jdk1.7之后移除永久代),已确定的符号引用和虚方法表等等,它几乎是静态的很少被回收,在jdk8之前的hotspot虚拟机中,类的这些”永久的”数据存放在一个叫做永久代的区域,在jvm启动时可以设置-XX:MaxPermsize的值来控制永久代的大小,但是jdk1.8之后取消了永久代,这些元素被移到了与堆不相连的本地内存区域

Gc参数

hotspot实现垃圾回收细节

一致性

一致性要求gc进行时必须停顿所有java执行线程

安全点

程序只有达到安全点才能暂停,安全点的标准就是是否让程序长时间执行的特征,比如方法调用和循环跳转这种,具有这些才会产生安全点

程序暂停的2种方式

抢先式中断:在gc发生时,主动中断所有线程

主动式中断:设一个标志,各线程去轮询这个标志,遇到中断则暂停,轮询地方与安全点重合

垃圾收集器

Serial收集器

Serial收集器是最基本,发展历史最悠久的收集器,曾经(在jdk1.3.1之前)是虚拟机新生代收集的唯一选择

这是一个单线程收集器。意味着它只会使用一个 CPU 或一条收集线程去完成收集工作,并且在进行垃圾回收时必须暂停其它所有的工作线程直到收集结束。

它的优势在于简单而高效,对于限定单个CPU来说,由于serial收集器没有线程交互的开销,专心做垃圾收集自然能获得最高的单线程收集效率

ParNew 收集器

ParNew收集器其实就是serial收集器的多线程版本,除了使用多线程执行垃圾回收外,其余行为跟serial收集器一模一样,例如在回收算法和回收策略,分配规则都是一样的,在实现上这2种收集器共用了很多代码

Parnew的应用场景:是运行在server模式下的虚拟机的首选新生代垃圾回收器,因为它是除serial收集器外唯一能与cms收集器配合工作

Serial收集器与parnew收集器比较

Parnew收集器在单cpu环境下绝对不会比serial收集器有更好的效果,因为它存在线程的交互开销,但是随着可以使用的CPU数量增加,它对于gc时系统资源的有效利用还是很好的

Parallel Scavenge 收集器

是一个新生代收集器,也是使用复制算法实现,同时也是并行的多线程收集器。应用场景主要是针对那些需要频繁与用户交互的程序,良好的响应速度能提升用户体验

Serial Old 收集器

Serial收集器的老年代版本,单线程,使用 标记 —整理算法。

应用场景:

Client模式:serial old收集器主要意义在于给client模式下的虚拟机使用

Server模式:在server模式下有2大用途:一种用途是在jdk1.5之前与Parallel Scavenge 收集器配合使用,另一种用途是作为cms收集器的备用预案,在并发收集失败时使用

Parallel Old 收集器

Parallel Old 是 Parallel Scavenge 收集器的老年代版本。多线程,使用 标记 — 整理算法

应用场景:在注重吞吐量以及CPU资源敏感的场合,可以优先考虑Parallel Old 和 Parallel Scavenge 收集器

这个收集器是在jdk1.6中才提供的

CMS 收集器

CMS (Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间为目标的收集器。基于 标记 —清除算法实现。

运作步骤:

初始标记(CMS initial mark):标记 GC Roots 能直接关联到的对象,需要”stop the world”

并发标记(CMS concurrent mark):进行 GC Roots Tracing

重新标记(CMS remark):修正并发标记期间的变动部分,仍然需要”stop the world”

并发清除(CMS concurrent sweep):会清除对象

缺点:

1,cms收集器对CPU资源比较敏感,cms默认启动的回收线程数是(CPU数量+3)/4,也就是CPU在4个以上时,并发回收时垃圾收集线程不少于25%的CPU资源,并随着CPU数量的增加而下降,但是,如果CPU不足4个时,cms对用户程序的影响变得很大

2,cms收集器无法处理浮动垃圾,可能出现”concurrent mode failure”失败而导致另一次full gc产生

3,cms收集器会产生大量空间碎片,因为它是基于标记-清除算法的收集器,故在收集结束时会产生大量空间碎片,空间碎片过多会给大对象分配带来很大麻烦,比如老年代还有很大空间剩余,但是无法找到更大的连续空间来分配对象从而不得不提前触发一次full gc

G1 收集器

G1(garbage first)是一款面向服务端应用的垃圾收集器,Hotspot开发团队是希望用它替换掉jdk1.5中发布的cms收集器

G1的优点:并行与并发、分代收集、空间整合、可预测停顿。

运作步骤:

初始标记(Initial Marking)

并发标记(Concurrent Marking)

最终标记(Final Marking)

筛选回收(Live Data Counting and Evacuation)

实例分析

实例1

java.lang.OutOfMemoryError: GC overhead limit exceeded

通过Linux查看进程的命令ps -ef|grep java发现

-xms768m -xmx768m -xx:NewSize=320m, -xx:MaxNewSize=320m

通过分析应用堆区内存设置只有768m,机器内存有2g,机器上只跑了一个java应用,没有其他需要占内存的地方,另外,这个应用比较大,需要占得内存比较比较多所以修改配置如下

-xms1280m -xmx1280m -xx:NewSize=500m, -xx:MaxNewSize=500m

跟踪运行情况发现,异常没有再出现,问题解决

实例2

一个服务系统,经常出现卡顿,分析原因,发现full gc时间太长

Jstat -gcutil:

S0 S1 E O P YGC YGCT FGC FGCT GCT

12.16 0.00 5.18 63.78 20.32 54 2.047 5 6.946 8.993

分析上面的数据,发现YGC执行54次,耗时2.047秒,每次YGC耗时37ms,在正常范围,而FGC执行了5次,耗时6.946秒,每次耗时1.389秒数据显示问题

Full gc耗时较长,分析该系统发现-XX:NewRadio=9,也就是新生代和老年代的比例是1:9

这会造成:

1,新生代内存太小,导致对象提前进入老年代,从而触发full gc

2,老年代较大,进行full gc耗时较长

解决方法是将-XX:NewRadio=4,意思是将对象控制在新生代就清理掉,没有进入老年代(这种做法针对一些应用有效,并不是所有应用都有效)

总结

1,多数的Java应用不需要在服务器上进行GC优化;

2,多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;

3,在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合)

4,减少创建对象的数量

5,减少使用全局变量和大对象;

6,GC优化是到最后不得已才采用的手段

7,在实际使用中,分析GC情况优化代码比优化GC参数要多得多

GC优化的目的有2个

1,将转移到老年代的对象数量降低到最少

2,减少full gc的执行时间

为达目的可以这样做:

1,减少使用全局变量和大对象

2,调整新生代的大小到最合适

3,设置老年代的大小为最合适

4,选择合适的GC收集器 返回搜狐,查看更多

责任编辑:

平台声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()
推荐阅读

4617作文网起名械囊馑卢姓名字女孩起名大全易周取名字大全牛年宝宝起名大全男孩免费梦解梦大全查询肯尼亚中国贸易周周易取名字免费周公解梦梦见捡到金项链有创意的装修公司起名大全电动车配件起名大全梦幻农场破解版股票每周交易时间会计公司起名子盗梦空间解析图动感单车课起名费氏专业起名软件开小饭店起名字周公解梦大全查询梦见牙齿松动马姓小妮起名汽车运输公司起名字昆明算命带晟的公司起名字姓张秀字辈的起名周易免费命理大全高功能周易大师周易是易经么浠字起名含义好不算命生辰八字属狗宝宝起名宜用字左右为孩子起名字淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男子给前妻转账 现任妻子起诉要回网友建议重庆地铁不准乘客携带菜筐月嫂回应掌掴婴儿是在赶虫子重庆警方辟谣“男子杀人焚尸”国产伟哥去年销售近13亿新的一天从800个哈欠开始男孩疑遭霸凌 家长讨说法被踢出群高中生被打伤下体休学 邯郸通报男子持台球杆殴打2名女店员被抓19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警两大学生合买彩票中奖一人不认账德国打算提及普京时仅用姓名山西省委原副书记商黎光被逮捕武汉大学樱花即将进入盛花期今日春分张家界的山上“长”满了韩国人?特朗普谈“凯特王妃P图照”王树国3次鞠躬告别西交大师生白宫:哈马斯三号人物被杀代拍被何赛飞拿着魔杖追着打315晚会后胖东来又人满为患了房客欠租失踪 房东直发愁倪萍分享减重40斤方法“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火手机成瘾是影响睡眠质量重要因素考生莫言也上北大硕士复试名单了妈妈回应孩子在校撞护栏坠楼网友洛杉矶偶遇贾玲呼北高速交通事故已致14人死亡西双版纳热带植物园回应蜉蝣大爆发男孩8年未见母亲被告知被遗忘张立群任西安交通大学校长恒大被罚41.75亿到底怎么缴沈阳一轿车冲入人行道致3死2伤奥运男篮美国塞尔维亚同组周杰伦一审败诉网易国标起草人:淀粉肠是低配版火腿肠外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万杨倩无缘巴黎奥运男子被猫抓伤后确诊“猫抓病”春分“立蛋”成功率更高?记者:伊万改变了国足氛围奥巴马现身唐宁街 黑色着装引猜测

4617作文网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化