游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

JVM性能调优之内存优化与GC优化

  JVM调优是一个系统而又复杂的过程,但我们知道,在大多数情况下,我们基本不用去调整JVM内存分配,因为一些初始化的参数已经可以保证应用服务正常稳定地工作了。
  在应用服务的特定场景下,JVM内存分配不合理带来的性能表现并不会像内存溢出问题这么突出。一般你没有深入到各项性能指标中去,是很难发现其中隐藏的性能损耗。
  压测工具AB
  Ab(ApacheBench)测试工具是Apache提供的一款测试工具,具有简单易上手的特点,在测试Web服务时非常实用。
  ab一般都是在Linux上用。
  安装非常简单,只需要在Linux系统中输入yumyinstallhttpdtools命令,就可以了。
  安装成功后,输入ab命令,可以看到以下信息:
  ab工具用来测试postget接口请求非常便捷,可以通过参数指定请求数、并发数、请求参数等。
  参数的含义:
  n:总请求次数(最小默认为1);
  c:并发次数(最小默认为1且不能大于总请求次数,例如:10个请求,10个并发,实际就是1人请求1次);
  p:post参数文档路径(p和T参数要配合使用);
  T:header头内容类型(此处切记是大写英文字母T);
  输出中,性能指标参考:
  Requestspersecond:吞吐率,指某个并发用户数下单位时间内处理的请求数;
  Timeperrequest:上面的是用户平均请求等待时间,指处理完成所有请求数所花费的时间(总请求数并发用户数);
  Timeperrequest:下面的是服务器平均请求处理时间,指处理完成所有请求数所花费的时间总请求数;
  Percentageoftherequestsservedwithinacertaintime:每秒请求时间分布情况,指在整个请求中,每个请求的时间长度的分布情况,例如有50的请求响应在8ms内,66的请求响应在10ms内,说明有16的请求在8ms10ms之间。
  JVM堆内存分配
  JVM内存分配的调优案例
  一个高并发系统中的抢购接口,高峰时5W的并发请求,且每次请求会产生20KB对象(包括订单、用户、优惠券等对象数据)。
  我们可以通过一个并发创建一个1MB对象的接口来模拟万级并发请求产生大量对象的场景,具体代码如下:
  AB压测
  对应用服务进行压力测试,模拟不同并发用户数下的服务的响应情况:
  1、10个并发用户10万请求量(总)
  2、100个并发用户10万请求量(总)
  3、1000个并发用户10万请求量(总)
  abc10n100000http:127。0。0。1:8080jvmheap
  abc100n100000http:127。0。0。1:8080jvmheap
  abc1000n100000http:127。0。0。1:8080jvmheap
  服务器信息
  我本机起一台Linux虚拟机,分配的内存为2G,处理器数量为2个。具体信息如下图:
  GC监控
  还有一句话,无监控不调优,所以我们需要监控起来。JVM中我们使用jstat命令监控一下JVM的GC情况。
  统计GC的情况:jstatgc8404500020awk{print13,14,15,16,17}。
  堆空间监控
  在默认不配置JVM堆内存大小的情况下,JVM根据默认值来配置当前内存大小。
  我们可以通过以下命令来查看堆内存配置的默认值:javaXX:PrintFlagsFinalversiongrepHeapSize。
  这台机器上启动的JVM默认最大堆内存为480MB,初始化大小为32MB。
  测试项目启动
  使用jmapheap这种方式,我们看到这个JVM应用占据的堆空间大小。
  压测结果
  1、10个并发用户10万请求量(总)
  使用AB进行压力测试:abc10n100000http:127。0。0。1:8080jvmheap。
  统计GC情况
  jstatgc9656500020awk{print13,14,15,16,17}。
  测试结果显示:
  用户的吞吐量大于在1426每秒左右;
  JVM服务器平均请求处理时间0。7ms左右;
  JVM服务器发生了2700多次YGC,耗时15秒,还有45次FGC,2。3秒左右,加在一起GC耗时17秒。
  2、100个并发用户10万请求量(总)
  使用AB进行压力测试:abc100n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1262每秒左右;
  JVM服务器平均请求处理时间0。8ms左右;
  JVM服务器发生了2700多次YGC,耗时30秒,还有56次FGC,3秒左右,加在一起GC耗时33秒。
  3、1000个并发用户10万请求量(总)
  使用AB进行压力测试:abc1000n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1145每秒左右;
  JVM服务器平均请求处理时间0。8ms左右;
  JVM服务器发生了2700多次YGC,耗时38秒,还有47次FGC,3秒左右,加在一起GC耗时42秒。
  结果分析
  GC频率
  高频的FullGC会给系统带来非常大的性能消耗,虽然MinorGC相对FullGC来说好了许多,但过多的MinorGC仍会给系统带来压力。
  内存
  这里的内存指的是堆内存大小,堆内存又分为年轻代内存和老年代内存。堆内存不足,会增加MinorGC,影响系统性能。
  吞吐量
  频繁的GC将会引起线程的上下文切换,增加系统的性能开销,从而影响每次处理的线程请求,最终导致系统的吞吐量下降。
  延时
  JVM的GC持续时间也会影响到每次请求的响应时间。
  调优方案
  调整方案一
  调整堆内存空间减少GC:通过分析,堆内存基本被用完了,而且存在大量MinorGC和FullGC,这意味着我们的堆内存严重不足,这个时候我们需要调大堆内存空间。
  堆空间加大到1。5G
  javajarXms1500mXmx1500mjvm1。0SNAPSHOT。jar。
  使用AB进行压力测试:abc10n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1205每秒左右
  JVM服务器平均请求处理时间0。83ms左右
  JVM服务器发生了800次YGC,耗时33秒,还有1次FGC,1秒左右,加在一起GC耗时34秒
  使用AB进行压力测试:
  abc100n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在989每秒左右
  JVM服务器平均请求处理时间1。01ms左右
  JVM服务器发生了800次YGC,耗时46秒,还有8次FGC,6秒左右,加在一起GC耗时52秒
  使用AB进行压力测试:
  abc1000n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在749每秒左右
  JVM服务器平均请求处理时间1。3ms左右
  JVM服务器发生了800次YGC,耗时66秒,还有8次FGC,9秒左右,加在一起GC耗时75秒
  调整方案二
  javajarXms1500mXmx1500mXmn1000mXX:SurvivorRatio8jvm1。0SNAPSHOT。jar
  使用AB进行压力测试:
  abc10n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1780每秒左右
  JVM服务器平均请求处理时间0。56ms左右
  JVM服务器发生了400次YGC,耗时5。8秒,还有2次FGC,0。1秒左右,加在一起GC耗时6秒
  使用AB进行压力测试:
  abc100n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1927每秒左右
  JVM服务器平均请求处理时间0。51ms左右
  JVM服务器发生了400多次YGC,耗时11秒,没有FGC,加在一起GC耗时11秒
  使用AB进行压力测试:
  abc1000n100000http:127。0。0。1:8080jvmheap。
  测试结果显示:
  用户的吞吐量大于在1657每秒左右
  JVM服务器平均请求处理时间0。6ms左右
  JVM服务器发生了400多次YGC,耗时14秒,还1次FGC,3秒左右,加在一起GC耗时17秒
  内存优化总结
  一般情况下,高并发业务场景中,需要一个比较大的堆空间,而默认参数情况下,堆空间不会很大。所以我们有必要进行调整。
  但是不要单纯的调整堆的总大小,要调整新生代和老年代的比例,以及Eden区还有From区,还有To区的比例。
  所以在我们上述的测试中,调整方案二,得到结果是最好的。在三种测试情况下都能够有非常好的性能指标,同时GC耗时相对控制也较好。
  对于调整方案一,就是单纯的加大堆空间,里面的比例不适合高并发场景,反而导致堆空间变大,没有明显减少GC的次数,但是每次GC需要检索对象的堆空间更大,所以GC耗时更长。
  方案二:调整为一个很大的新生代和一个较小的老年代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而老年代尽存放长期存活对象。
  由于新生代空间较小,Eden区很快被填满,就会导致频繁MinorGC,因此我们可以通过增大新生代空间来降低MinorGC的频率。单次MinorGC时间是由两部分组成:T1(扫描新生代)和T2(复制存活对象)。
  默认情况:一个对象在Eden区的存活时间为500ms,MinorGC的时间间隔是300ms,因为这个对象存活时间间隔时间,那么正常情况下,MinorGC的时间为:T1T2。
  方案一:整堆空间加大,但是新生代没有增大多少,对象在Eden区的存活时间为500ms,MinorGC的时间可能会扩大到400ms,因为这个对象存活时间间隔时间,那么正常情况下,MinorGC的时间为:T11。5(Eden区加大了)T2。
  方案二:当我们增大新生代空间,MinorGC的时间间隔可能会扩大到600ms,此时一个存活500ms的对象就会在Eden区中被回收掉,此时就不存在复制存活对象了,所以再发生MinorGC的时间为:即T12(空间大了)T20。
  可见,扩容后,MinorGC时增加了T1,但省去了T2的时间。
  在JVM中,复制对象的成本要远高于扫描成本。如果在堆内存中存在较多的长期存活的对象,此时增加年轻代空间,反而会增加MinorGC的时间。如果堆中的短期对象很多,那么扩容新生代,单次MinorGC时间不会显著增加。因此,单次MinorGC时间更多取决于GC后存活对象的数量,而非Eden区的大小。
  这个就解释了之前的内存调整方案中,方案一为什么性能还差些,但是到了方案二话,性能就有明显的上升。
  推荐策略
  1。新生代大小选择
  响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,新生代收集发生的频率也是最小的。同时,减少到达老年代的对象。
  吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。
  避免设置过小。当新生代设置过小时会导致:1。MinorGC次数更加频繁2。可能导致MinorGC对象直接进入老年代,如果此时老年代满了,会触发FullGC。
  2。老年代大小选择
  响应时间优先的应用:老年代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片,高回收频率以及应用暂停而使用传统的标记清除方式;
  如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:
  并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在新生代和老年代回收上的时间比例。
  吞吐量优先的应用:
  一般吞吐量优先的应用都有一个很大的新生代和一个较小的老年代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而老年代尽存放长期存活对象。
  GC优化
  GC性能衡量指标
  吞吐量:
  这里的衡量吞吐量是指应用程序所花费的时间和系统总运行时间的比值。我们可以按照这个公式来计算GC的吞吐量:系统总运行时间应用程序耗时GC耗时。如果系统运行了100分钟,GC耗时1分钟,则系统吞吐量为99。GC的吞吐量一般不能低于95。
  停顿时间:
  指垃圾回收器正在运行时,应用程序的暂停时间。对于串行回收器而言,停顿时间可能会比较长;而使用并发回收器,由于垃圾收集器和应用程序交替运行,程序的停顿时间就会变短,但其效率很可能不如独占垃圾收集器,系统的吞吐量也很可能会降低。
  垃圾回收频率:
  通常垃圾回收的频率越低越好,增大堆内存空间可以有效降低垃圾回收发生的频率,但同时也意味着堆积的回收对象越多,最终也会增加回收时的停顿时间。所以我们需要适当地增大堆内存空间,保证正常的垃圾回收频率即可。
  分析GC日志
  通过JVM参数预先设置GC日志,几种JVM参数设置如下:
  XX:PrintGC输出GC日志
  XX:PrintGCDetails输出GC的详细日志
  XX:PrintGCTimeStamps输出GC的时间戳(以基准时间的形式)
  XX:PrintGCDateStamps输出GC的时间戳(以日期的形式,如20130504T21:53:59。2340800)
  XX:PrintHeapAtGC在进行GC的前后打印出堆的信息
  Xloggc:。。logsgc。log日志文件的输出路径
  案例
  比如:导出前面测试案例中,默认情况下的gc日志
  javajarXX:PrintGCDateStampsXX:PrintGCDetailsXloggc:。gclogsjvm1。0SNAPSHOT。jar
  1、进行1000个并发用户10万请求量的压力测试,得到gclogs日志
  javajarXX:PrintGCDateStampsXX:PrintGCDetailsXloggc:。gc2logsXms1500mXmx1500mXmn1000mXX:SurvivorRatio8jvm1。0SNAPSHOT。jar
  2、进行1000个并发用户10万请求量的压力测试,得到gc2logs日志
  使用日志工具gcViewer,我们就暂停这项进行对比:
  明显第一个暂停总耗时比第二个要多很多,一个是58秒,一个是15秒左右,相差很多,这个本质上也可以分析出来,对于系统来说,第二个的GC日志情况更加的好。
  GC调优策略
  降低MinorGC频率
  由于新生代空间较小,Eden区很快被填满,就会导致频繁MinorGC,因此我们可以通过增大新生代空间来降低MinorGC的频率。单次MinorGC时间是由两部分组成:T1(扫描新生代)和T2(复制存活对象)。
  情况1:假设一个对象在Eden区的存活时间为500ms,MinorGC的时间间隔是300ms,因为这个对象存活时间间隔时间,那么正常情况下,MinorGC的时间为:T1T2。
  情况2:当我们增大新生代空间,MinorGC的时间间隔可能会扩大到600ms,此时一个存活500ms的对象就会在Eden区中被回收掉,此时就不存在复制存活对象了,所以再发生MinorGC的时间为:即T12(空间大了)T20。
  可见,扩容后,MinorGC时增加了T1,但省去了T2的时间。
  在JVM中,复制对象的成本要远高于扫描成本。如果在堆内存中存在较多的长期存活的对象,此时增加年轻代空间,反而会增加MinorGC的时间。如果堆中的短期对象很多,那么扩容新生代,单次MinorGC时间不会显著增加。因此,单次MinorGC时间更多取决于GC后存活对象的数量,而非Eden区的大小。
  这个就解释了之前的内存调整方案中,方案一为什么性能还差些,但是到了方案二话,性能就有明显的上升。
  降低FullGC的频率
  由于堆内存空间不足或老年代对象太多,会触发FullGC,频繁的FullGC会带来上下文切换,增加系统的性能开销。
  减少创建大对象:在平常的业务场景中,我们一次性从数据库中查询出一个大对象用于web端显示。比如,一次性查询出60个字段的业务操作,这种大对象如果超过年轻代最大对象阈值,会被直接创建在老年代;即使被创建在了年轻代,由于年轻代的内存空间有限,通过MinorGC之后也会进入到老年代。这种大对象很容易产生较多的FullGC。
  增大堆内存空间:在堆内存不足的情况下,增大堆内存空间,且设置初始化堆内存为最大堆内存,也可以降低FullGC的频率。
  选择合适的GC回收器
  如果要求每次操作的响应时间必须在500ms以内。这个时候我们一般会选择响应速度较快的GC回收器,堆内存比较小的情况下(6G)选择CMS(ConcurrentMarkSweep),如果回收器和堆内存比较大的情况下(8G)G1回收器。
  总结
  GC调优是个很复杂、很细致的过程,要根据实际情况调整,不同的机器、不同的应用、不同的性能要求调优的手段都是不同的,这些都需要大家平时去积累,去观察,去实践。
  如果本文对你有帮助,别忘记给我个3连,点赞,转发,评论,
  ,咱们下期见!答案获取方式:已赞已评已关

武则天墓为何40万人都挖不开,两位术士成就了这风水学的巅峰之盗墓,这是古来有之的行当。遍寻古今中外,没有哪个帝王的陵寝没有被盗墓贼觊觎过。马踏匈奴的汉武大帝够威武吧,他所安睡的茂陵却被盗墓贼搬了个精光。开创贞观之治的唐太宗够……抗美援朝选帅,刘帅军事素养极高,有丰富作战经验,为何没被启用正所谓千军易得一将难求,尤其是找一位出色的统帅,那难度是非常大的。新中国成立后,军队规模高达几百万,会打仗的将军有千余人之多,真正能统领大军作战,有丰富的大兵团指挥经验的却不多……原子弹爆炸核辐射影响可达上亿年,为何广岛长崎现在就能住人?1945年8月15日,日本宣布无条件投降,标志着第二次世界大战结束。战争结束后,美国和日本都表示:广岛和长崎在遭受核打击之后,至少是100年内都不能够再住人了。那为何实际……第四野战军12位代表合影,将近一半属虎,他们都是谁?1949年的金秋9月,新中国成立前夕,在北京召开了第一届全国政协会议。威震天下的第四野战军选出了12位代表,其中正式代表10人,候补代表2人。他们代表着兵力超过百万最强大……假设刘备没死,还统一三国当了皇帝,会第一时间杀谁?假设刘备没死,还统一三国当了皇帝的话,肯定是免不了和他的老祖宗刘邦一样要杀两位功臣的,因为这两人一人功高盖主,一人本质上并不是忠于刘备,这两人是谁呢?其一自然就是最强智囊诸葛亮……关岛是怎样落入美国手中的?大家好,我是五班长。关岛位于太平洋西部,总面积549平方公里,东距美国9800公里,西距我国3100公里,原为西班牙殖民地,1898年,美国通过美西战争打败了西班牙从而占……千年盛世原始千年卡牌介绍哈喽大家好呀,本期给大家带来的是有关千年盛世原始千年游戏中卡牌的属性和作用,以及它怎么获得。当进入游戏,在主页面中,玩家们会看到角色这个图标,进入角色这一页面之后在面板的……家中有菜,心里不慌,冬天需要囤的5菜,家常好吃又营养今年的冬天格外的寒冷,寒潮来势汹汹,再加上距离过年越来越近,囤菜,囤年货的进程也应该被提上日程了。北方人更有囤菜的习惯,但是在特殊的寒潮影响下,多囤些菜自然更为方便。分享……老头800万卖传家宝,文物局出价1万被拒,转身1800万被故1995年10月初,北京瀚海公司正在举行一场盛大的秋季拍卖会。一名着装朴素的东北老汉双手握拳站在拍卖会一角,两只眼睛紧紧盯着正在拍卖的文物。李老汉正是这件文物的主人……去年澳门博彩业总收入908亿澳门元按年增42中新社澳门10月25日电澳门特区政府统计暨普查局25日公布的数据显示,2021年澳门博彩业的总收入按年增加42至908。1亿元(澳门元,下同)。统计暨普查局资料显示,20……30岁的日子里还需如何去奋斗忙忙碌碌的一年又一年,把自己从青春年少熬到了中年,人生几何,匆匆的日子总是在不经意间悄悄流逝,仔细回想这些的年的日子,不禁感慨万千,时光如流水,总感觉大好的肆意青春没有开始,却……五六十岁女人,帽子尽量不要戴军帽和贝雷帽,这些更减龄好像一不小心就混到了老阿姨这个级别,年轻时可爱的针织帽、蓬蓬裙都还没穿够,又怎么能容许自己就这样在年龄中慢慢变土变丑呢?如果你也不想向年龄低头,那可就来对地方了有帽子在手……
妻子等了黄维27年,却在其出狱一年后自杀,究竟因为什么?苏轼曾说渺沧海之一粟,哀吾生之须臾,由此感叹人生短短不过几个秋,时间太短。而我们从小也熟知,一寸光阴一寸金,寸金难买寸光阴,更加佐证了时间的飞速。短短的27年,在漫漫历史……历史上跟康熙捉住鳌拜的那些少年,后来都什么下场?康熙八年(1669年)五月,康熙皇帝依靠着一群只有十多岁的布库少年在武英殿智擒鳌拜,从而将权力彻底收归到自己手中,并就此开创了一代王朝盛世。在这之后,这些原本就是上三旗子……晋台遥想肖庄镇百枣玫瑰生态园的晋台周末下午,我独自驱车来到茌平县肖庄镇百枣玫瑰生态园,走近晋台晚照景点,瞻仰晋文公雕像,登上望晋台,面朝西方,面向夕阳,望着万亩枣园延伸到的远方,……湘军名将之后天性乐观幽默的陈赓大将,为何英年早逝1961年3月16日,上海,春寒料峭。昨晚临睡前,陈赓突然和夫人傅涯回忆往事,相识、相恋、相知相守。一对知心爱人,陷入沉浸式体验中,睡得较晚。陈赓和夫人傅涯8……放弃壁挂和座装,选择索见移动电视支架,实用便利,兼顾美感前言大家好,我是你们的老朋友sevokk,很高兴又和大家见面了。新家装修完成,接着就是各种硬装、软装、家电的补齐。电视我选择了一款非常热门的性价比国货:荣耀智慧屏X2,色……媒体人李霄鹏是临时主帅冬奥会后总局洗牌!足球会有新的规划根据媒体人《半岛都市报》体育主任崔恒亮的观点,即使李霄鹏替代李铁成为新任的国足主帅,也极有可能是一名临时主帅。崔恒亮表示:国足新帅的确需要有长远考虑,为了下届亚洲杯和世界……友商怕了吗?华为nova11关键参数确认,骁龙778G照样受华为nova11定档4月17日发布,目前官方正处于密集预热阶段,网上曝光参数图显示新机没有骁龙8版本,全系搭载骁龙778G处理器。尽管如此,粉丝依旧对新机抱有极高的热情,认为华……北京又一处长城开放夜游,怎么约怎么玩看这里本文将占用您5分钟的阅读时间但会回报您10分的精彩之前咱们介绍过,北京可以夜游长城的两个地方,分别是位于密云的司马台长城和位于延庆的八达岭长城。精彩回顾:……她是邓小平的第二任妻子,后来嫁给李维汉,生下的儿子成了副国级中国社会的发展史上,涌现出了许许多多的优秀女性。谋略,才识,一点都不输于男子,以自身坚韧的韧性,谱写生命的赞歌。为中国之复兴而上下求索、四处奔走,以实际行动捍卫了祖国民族的尊严……1992年,已经74岁陈赓大将的妻子傅涯,不顾劝阻,执意要去1992年,经历过抗日战争、解放战争的女革命家傅涯,年轻的风韵已不再,成了一名头发花白的老太太。她在收到了一封美国的来信后,满眼含泪,内心久久不能平静。已经74岁高龄的她告诉家……低迷下跌!11月3日有色金属价格行情长江现货:1铜:6476064800元吨,跌210元。A00铝:1822018260元吨,涨260元。1铅:1505015150元吨,跌50元。0锌:2390……1974年,88岁高龄的朱老总痛失独子,两年后他也离开了人世1976年,朱老总因病逝世。他的离世,让多少人哭红了眼睛。没有人敢相信一直爽朗豁达的朱老总,就这样一动不动躺在病床上。身边的人还期盼着他能够活到100岁,但是朱老总却在9……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网