GC发生在JVM那一部分?有几种GC?他们的算法是什么?
GC发生在JVM堆(Heap)里
堆区:内存最大的一块,所有的对象实例都在这里分配内存
GC 是分代手机算法,不同的对象生命周期不同。把不同生命周期的对象放在不同代上,不同代上采用最合适它的垃圾回收方式进行回收。
- 次数上频繁收集Young区 MinorGC(存放所有新生成的对象)
- 次数上较少收集Old区 Full GC(在年轻代中经历了N次垃圾回收仍然存活的对象,将被放到年老代中,故都是一些生命周期较长的对象)
- 基本不动Perm区(用于存放静态文件,如Java类、方法等)
GC算法:
应用:微软的COM/ActionScript3/Python......
缺点:每次对对象复制时均需要维护引用计数器,而且计数器本身也有一定的消耗;
较难处理循环引用
- 复制算法(Copying)
年轻代中使用的Minor GC,就是才用的复制算法(Copying)
原理:
从根集合(GC Root)开始,通过Tracing从Form中找到存活对象,拷贝到To中;
Form、To交换身份,下次内存从To开始
优点:
没有标记和清除的过程,效率高
没有内存碎片,可以利用bump-the-pointer实现快速内存分配
缺点:需要双倍空间
- 标记清除(Mark-Sweep)
老年代一般是由标记清除或者标记清除与标记整理的混合实现
标记(Mark):从根集合开始扫描,对存活的对象进行标记。
清除(Sweep):扫描整个内存空间,回收未被标记的对象,使用free-list记录可以区域
优点:不需要额外空间
缺点:
两次扫描,耗时严重
会产生内存碎片
- 标记压缩(Mark-Compact)
老年代一般是由标记清除或者标记清除与标记整理的混合实现
标记(Mark):从根集合开始扫描,对存活的对象进行标记。
压缩(Compact):再次扫描,并往一端滑动存活对象
优点:没有内存碎片,可以利用bump-the-pointe
缺点:需要移动对象的成本
- 标记清除压缩(Mark-Sweep-Compact)
原理:
Mark-Sweep 和 Mark-Compact的结合
和Mark-Sweep 一致,当进行多次GC后才Compact
优点:减少移动对象的成本