1. 堆的分布
-
1.1 堆的分布图
image.png
1. java堆被划分成不同的区域:新生代 ( Young )、老年代 ( Old )
2. 新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。
3. 新生代占整个堆的1/3、Eden占新生代的1/8、from和to的大小一致各占新生代1/10、老年代占2/3
4.from区和to去的大小空间是一样的,为什么呢?因为YGC 采用复制算法
2. GC的算法
-
2.1 标记-清除
标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象;然后,在清除阶段,清除所有未被标记的对象。
image.png - 2.1.1 标记-清除算法的缺点:
1.它的缺点就是效率比较低(递归与全堆对象遍历),导致stop the world的时间比较长
2.这种方式清理出来的空闲内存是不连续的
-
2.2 标记压缩
标记-压缩算法适合用于存活对象较多的场合,如老年代。它在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记;但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端;之后,清理边界外所有的空间。
image.png - 2.2.1 标记-压缩算法的缺点:
1.如果在对象存活率较高时就要进行较多的复制操作,效率将会变低。
2.更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选中这种算法。
-
2.3 复制算法
与标记-清除算法相比,复制算法是一种相对高效的回收方法
不适用于存活对象较多的场合,如老年代(复制算法适合做新生代的GC)
将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。
image.png - 2.3.1 复制算法的缺点:
1.复制算法的最大的问题是:空间的浪费
3. GC的触发
image.png