分析
当频繁full gc时,jstack打印出堆栈信息如下:
sudo -u admin -H /opt/taobao/java/bin/jstack `pgrep java` > #your file path#
可以看到的确是在跑低价信息
另外在应用频繁full gc时和应用正常时,也执行了如下2种命令:
sudo -u admin -H /opt/taobao/java/bin/jmap -histo `pgrep` > #your file path#
sudo -u admin -H /opt/taobao/java/bin/jmap -histo:live `pgrep` > #your file path#(live会产生full gc)
目的是确认以下2种信息:
(1)是否存在某些引用的不正常,造成对象始终可达而无法回收(Java中的内存泄漏)
(2)是否真是由于在频繁full gc时同时又有大量请求进入分配内存从而处理不过来,
造成concurrent mode failure?
下图是在应用正常情况下,jmap不加live,产生的histo信息:
下图是在应用正常情况下,jmap加live,产生的histo信息:
下图是在应用频繁full gc情况下,jmap不加live和加live,产生的histo信息:
从上述几个图中可以看到:
(1)在应用正常情况下,图中标红的对象是被回收的,因此不是内存泄漏问题
(2)在应用频繁full gc时,标红的对象即使加live也是未被回收的,因上就是在频繁full gc时,
同时又有大量请求进入分配内存从而处理不过来的问题
先从解决问题的角度,看怎样造成频繁的full gc?
从分析CMS GC开始
先给个CMS GC的概况:
(1)young gc
可以看到,当eden满时,young gc使用的是ParNew收集器
ParNew: 2230361K->129028K(2403008K), 0.2363650 secs解释:
1)2230361K->129028K,指回收前后eden+s1(或s2)大小
2)2403008K,指可用的young代的大小,即eden+s1(或s2)
3)0.2363650 secs,指消耗时间
2324774K->223451K(3975872K), 0.2366810 sec解释:
1)2335109K->140198K,指整个堆大小的变化
(heap=(young+old)+perm;young=eden+s1+s2;s1=s2=young/(survivor ratio+2))
2)0.2366810 sec,指消耗时间
[Times: user=0.60 sys=0.02, real=0.24 secs]解释:指用户时间,系统时间,真实时间
(2)cms gc
当使用CMS收集器时,当开始进行收集时,old代的收集过程如下所示:
a)首先jvm根据-XX:CMSInitiatingOccupancyFraction,-XX:+UseCMSInitiatingOccupancyOnly
来决定什么时间开始垃圾收集
b)如果设置了-XX:+UseCMSInitiatingOccupancyOnly,那么只有当old代占用确实达到了
-XX:CMSInitiatingOccupancyFraction参数所设定的比例时才会触发cms gc
c)如果没有设置-XX:+UseCMSInitiatingOccupancyOnly,那么系统会根据统计数据自行决定什么时候
触发cms gc;因此有时会遇到设置了80%比例才cms gc,但是50%时就已经触发了,就是因为这个参数
没有设置的原因
d)当cms gc开始时,首先的阶段是CMS-initial-mark,此阶段是初始标记阶段,是stop the world阶段,
因此此阶段标记的对象只是从root集最直接可达的对象
CMS-initial-mark:961330K(1572864K),指标记时,old代的已用空间和总空间
e)下一个阶段是CMS-concurrent-mark,此阶段是和应用线程并发执行的,所谓并发收集器指的就是这个,
主要作用是标记可达的对象
此阶段会打印2条日志:CMS-concurrent-mark-start,CMS-concurrent-mark
f)下一个阶段是CMS-concurrent-preclean,此阶段主要是进行一些预清理,因为标记和应用线程是并发执行的,
因此会有些对象的状态在标记后会改变,此阶段正是解决这个问题
因为之后的Rescan阶段也会stop the world,为了使暂停的时间尽可能的小,也需要preclean阶段先做一部分
工作以节省时间
此阶段会打印2条日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean
g)下一阶段是CMS-concurrent-abortable-preclean阶段,加入此阶段的目的是使cms gc更加可控一些,
作用也是执行一些预清理,以减少Rescan阶段造成应用暂停的时间
此阶段涉及几个参数:
-XX:CMSMaxAbortablePrecleanTime:当abortable-preclean阶段执行达到这个时间时才会结束
-XX:CMSScheduleRemarkEdenSizeThreshold(默认2m):控制abortable-preclean阶段什么时候开始执行,
即当eden使用达到此值时,才会开始abortable-preclean阶段
-XX:CMSScheduleRemarkEdenPenetratio(默认50%):控制abortable-preclean阶段什么时候结束执行
此阶段会打印一些日志如下:
CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,
CMS:abort preclean due to time XXX
h)再下一个阶段是第二个stop the world阶段了,即Rescan阶段,此阶段暂停应用线程,对对象进行重新扫描并
标记
YG occupancy:964861K(2403008K),指执行时young代的情况
CMS remark:961330K(1572864K),指执行时old代的情况
此外,还打印出了弱引用处理、类卸载等过程的耗时
i)再下一个阶段是CMS-concurrent-sweep,进行并发的垃圾清理
j)最后是CMS-concurrent-reset,为下一次cms gc重置相关数据结构
(3)full gc:
有2种情况会触发full gc,在full gc时,整个应用会暂停
a)concurrent-mode-failure:当cms gc正进行时,此时有新的对象要进行old代,但是old代空间不足造成的
b)promotion-failed:当进行young gc时,有部分young代对象仍然可用,但是S1或S2放不下,
因此需要放到old代,但此时old代空间无法容纳此
频繁full gc的原因
从日志中可以看出有大量的concurrent-mode-failure,因此正是当cms gc进行时,有新的对象要进行old代,
但是old代空间不足造成的full gc
进程的jvm参数如下所示:
影响cms gc时长及触发的参数是以下2个:
-XX:CMSMaxAbortablePrecleanTime=5000
-XX:CMSInitiatingOccupancyFraction=80
解决也是针对这两个参数来的
根本的原因是每次请求消耗的内存量过大
解决
(1)针对cms gc的触发阶段,调整-XX:CMSInitiatingOccupancyFraction=50,提早触发cms gc,就可以
缓解当old代达到80%,cms gc处理不完,从而造成concurrent mode failure引发full gc
(2)修改-XX:CMSMaxAbortablePrecleanTime=500,缩小CMS-concurrent-abortable-preclean阶段
的时间
(3)考虑到cms gc时不会进行compact,因此加入-XX:+UseCMSCompactAtFullCollection
(cms gc后会进行内存的compact)和-XX:CMSFullGCsBeforeCompaction=4
(在full gc4次后会进行compact)参数
但是运行了一段时间后,只不过时间更长了,又会出现频繁full gc
计算了一下heap各个代的大小(可以用jmap -heap查看):
total heap=young+old=4096m
perm:256m
young=s1+s2+eden=2560m
young avail=eden+s1=2133.375+213.3125=2346.6875m
s1=2560/(10+1+1)=213.3125m
s2=s1
eden=2133.375m
old=1536m
可以看到eden大于old,在极端情况下(young区的所有对象全都要进入到old时,就会触发full gc),
因此在应用频繁full gc时,很有可能old代是不够用的,因此想到将old代加大,young代减小
改成以下:
-Xmn1920m
新的各代大小:
total heap=young+old=4096m
perm:256m
young=s1+s2+eden=1920m
young avail=eden+s1=2133.375+213.3125=1760m
s1=1760/(10+1+1)=160m
s2=s1
eden=1600m
old=2176m
此时的eden小于old,可以缓解一些问题
改完之后,运行了2天,问题解决,未频繁报full gc
https://my.oschina.net/goldwave/blog/168516
相关推荐
关于锌施用方法的影响,成熟期最大株高(103.6 cm),分till总数(564.67 m-2),穗长(10.83 cm),小穗穗数1(19.50),穗穗数在施用锌的处理中记录了1(50.36),1000粒重(34.16 g),生物产量(11.93 t·ha-1...
农药施用技术及要求.pdf
以未破坏地块为对照,对每个地块分6个层次采集土壤样品进行分析,采用英国的马尔文激光粒度仪测量土壤颗粒组成,通过SPSS分析各地块与未破坏地块土壤颗粒组成的相关性。结果表明:蘑菇废料对土壤颗粒组成的影响实质是...
本文将深入探讨钼肥的种类、施用技术,以及其在土壤中的残效问题。 钼肥主要分为两大类:钼酸铵和钼酸钠。这两种肥料均具有很高的水溶性,因此它们不仅适用于传统的土壤施肥,而且还可以通过叶面喷施和种子处理的...
综上所述,"数字通信系统中藉施用于训练序列之相位旋转因子进行调变型态之传输及辨识"这一主题涵盖了数字通信的核心概念,包括训练序列的作用、相位旋转因子的影响、调变型态的选择以及如何在实际通信中有效地应用...
硝酸铵和硫硝酸铵区别及施用方法.doc
为揭示施用蘑菇料对煤矿区复垦土壤物理性状的影响,以未破坏土地为对照,布置了9个采样点,分析了施用蘑菇料对复垦土壤紧实度、密度、含水量、土壤颗粒类型(黏粒、粉粒、砂粒)等物理性状的影响。结果表明:随着时间的...
不同生物有机肥品种、施用量及施用方法对压砂西瓜生长及产量的影响,谭军利,王西娜,为探讨在压砂地上合理施用生物有机肥技术,本文通过三因素三水平的田间正 交试验研究了生物有机肥品种、施肥量和施肥方法对压砂...
但随着长期的耕作和化肥的不合理使用,黑土土壤的酸化现象越来越严重,这直接影响了土壤的肥力和农作物的产量,成为了当前农业生产中急需解决的问题。 首先,黑土酸化的原因主要是长期大量施用氮肥,尤其是尿素。...
本文件“行业分类-外包设计-用于通过接嘴施用制品的带角撑板的平面状软包装袋的介绍分析”将深入探讨这一主题,尤其关注带有角撑板的平面状软包装袋的设计特点和应用。 首先,软包装袋设计通常涉及材料选择、结构...
本行业文档详细介绍了“一种不同肥料同时施用的施肥装置”,旨在解决传统施肥方法中肥料混合不均、施用不便等问题,以实现更高效、更精确的农田管理。 这种施肥装置的核心设计理念在于实现多种肥料的同时施用,它...
【大棚蔬菜种植管理中存在的问题及解决措施分析】 随着现代农业技术的发展,大棚蔬菜种植已经成为我国农业领域的重要组成部分,它打破了传统种植的时空限制,使得反季节蔬菜成为可能。然而,大棚种植在实践中面临...
它们涉及的是农业领域,特别是关于长期施用有机物料对黄土高原土壤结构和有机碳影响的学术研究。不过,如果这里有一个隐藏的IT相关知识点,比如数据处理、文件压缩或信息检索,那么我可以提供以下内容: 在IT领域,...
综上所述,农药及残留成分的分析是一个涉及多个领域的科学问题,需要食品化学、环境科学和分子生物学等多个学科领域的专家共同参与解决。只有通过科学合理的农药使用和严格的残留监控,才能实现既保障农业生产效益,...
12-4各地区耕地灌溉面积和农用化肥施用情况(2018年)._ODName12-4 各地区耕地灌溉面积和农用化肥施用情况(2018年).xls
研究选取北京郊区农田作为实验对象,分别采集了施用过生物农药(Bt、苦参碱)和化学农药(多菌灵、敌敌畏)以及未施用过农药的农田土壤样品,进而分析土壤微生物的数量和多样性变化。 研究发现,化学农药对土壤...
本研究聚焦于探讨生物质炭和磷肥施用对小白菜(Brassica chinensis)这一常见蔬菜品种的生物量及养分含量的影响。研究的目的是为本地区生物质资源的有效利用、土壤改良以及蔬菜的安全生产提供理论依据。 生物质炭是...
### 方差分析——以单因素一元方差分析为例 #### 一、方差分析概述 方差分析(Analysis of Variance,简称ANOVA)是一种常用的统计方法,用于比较两个或多个样本群体之间的均值差异是否显著。根据自变量个数的不同...