gc 问题理解

定义计时单位t,一般对象的寿命从1t到10t不等,长对象为mt不死,对象大小均为s,内存空间大小es,s0s,s1s,os,ps 。单位时间产生不同生命周期的对象为……,那么假设5t时es填满,根据对象的寿命及生成时间点,有些对象被清除,剩余进入s0s。
假设对象生成是匀速的,gc周期也就基本固定,在多次gc后,s区填满,高龄对象进入old区
这样一来,影响内存使用的因素就比较明确了:
……

 
 

随着对象生成频率加快,gc发生的更加频繁,极端情况1t一次的话,对象基本无法在young被回收

 

简 化场景二: 对象都是等周期,匀速生成,在任意时间点的存活对象比例是固定的,看成是河流的水位,若对象周期大于gc周期水位将会高于eden容量,大量对象进入 tenured;正因为对象周期一般远小于gc周期,也就是水位远低于eden区才有了eden、survivor的结构。
那么随着生成速率加快,存活比例不变但水位上升,如果s区容量不小于水位,则tenured不增加;否则溢出到t区。

 

对场景扩展,有些对象生命周期大于两个gc周期,从eden到survivor后,再次gc仍然不能释放,需三次或者更多次才能释放,这样s区较eden区存活率更高。

 

再扩展,由于较长周期对象的存在,如果s区小于综合水位(e区转移加s区的),年长对象被移入t区,水位陡然下降。随着新对象产生,gc继续进行,水位再次上涨,周期性涨跌,t区不断积累。直到一次cmsgc产生释放提区空间。

 

如果对象的生命周期都是相同的,那么e,s区的存活率是一样的,在对象匀速产生的时候,水位也就不变了,要么都不会进入t区(s大于水位),要么总是有对象溢出到t区(s小于水位)。但是,现实不可是能匀速,在突发的时候就有可能水位高于s区,而溢出。

 

独立的几个问题,
如果对象生命都小于gc周期,那么,s区每次gc总是会被清空;
大于一个gc周期的对象,会被在s区多次移动,s增大,反而会使一些对象被移动次数增加;
通过增大s区减小高水位溢出;
通过调整threadhold减少因在s区之间的反复移动;
能否通过btrace跟踪gc移动了那些对象或者实例对应的类名;
如果tenured回收一个对象与eden相当,那么大于两个gc周期的对象移入t区都是划算的,但是由于t区存活率高的多且容量大,显然回收一个对象的代价更高

 

调整原则思考:

 · 晋升年龄(MaxTenuringThreshold),如果对象的生命周期两极分化良好,那么可以将threshold调小,这样能减少长对象在s区移动的代价。最优的情况是,在系统稳定运行一段时间后,oldGC频率不增加(或者oldGen增长率不变)

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值