扩容新生代为什么能够提高GC的效率
- 2022 年 1 月 26 日
- 筆記
- JVM和JUC中的问题
扩容新生代为什么能够提高GC的效率
该文章默认读者对JVM的基础有所了解
在学习JVM的时候,遇到了个人感觉比较有意思的问题,通过视频学习整理了一下。
先来上图:
大部分情况下,对象都会进入Eden区进行分配,当该空间满了以后,进行轻GC,如果对象存活,则会进入s0或者s1。
扩展:如何判断对象存活
采用根可达性分析算法来判断
可作为根的对象有:
- 虚拟机栈中引用的对象
- 本地方法栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区常量引用的对象
GC的耗时由两部分组成:
- 扫描整个新生代所要花费的时间
- 将存活对象复制到幸存区的时间
所以CG耗时=T1+T2;
假设:
新生代空间 (Space1): 200m,每隔5s GC一次,每次GC耗时100ms
GC=T1+T2=100ms
扩容新生代空间(Space2)(两倍): 400m,每隔10s GC一次,每次GC耗时200ms
GC=2*(T1+T2) =200ms ?(对不对)
其中我们需要考虑对象A的存活时间,它会影响到T2时间。
假设对象A存活时间:7S;
在Space1中 GC的时候对象A是存活的,那么就需要对对象进行移动,所以Space1中的GC=T1+T2。
在Space2中GC的时候对象A变为垃圾,那么就不需要对垃圾进行移动,所以在Space2中的GC=2*T1;
在垃圾回收算法中,JVM中移动内存对象的耗时比扫描(算法有优化)整个新生代的耗时是远远高于的。(前提条件)
由此可以得出,扩大新生代确实能够提高GC的效率,其中起决定的因素不是空间的大小,而是存活对象的大小;
增加整个空间的大小,可以拉长GC的间隔,从而尽可能的使得对象变为垃圾,来减少内存的移动。