-
判断一个对象是否是垃圾?
-
引用计数法。给对象添加一个引用计数器,当有一个地方引用它,计数器+1,当引用失效时,计数器-1,任何时刻计数器都为0的对象就是不能再被使用的
缺点:1、每次对对象赋值时都要维护引用计数器,且计数器本身也有一定的消耗,2、难以解决对象之间的循环引用问题。
-
可达性分析法。从一系列“GC Roots”的对象开始向下搜索,搜索所走过的路径称之为引用链。当一个对象到GC Roots没有任何引用链相连,则证明此对象是可回收的。<主流的Java虚拟机如HotSpot默认就是使用可达性分析管理内存>
Java中的GC Root对象:
- 虚拟机栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的独享
- 本地方法JNI引用的对象
-
-
常见的垃圾回收算法
-
复制算法:将可用内存按照容量分为相等的两份,每次只使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然后一次性清除第一块内存,再将第二块的对象复制到第一块。实现方便,运行高效,不考虑内存碎片,但内存利用率只有一半
-
标记-清除算法:分为标记和清除两个阶段。首先标记出所有需要回收的对象,在标记完成后统一回收被标记的对象。算法简单,但效率不高,标记和清除的效率都很低,空间问题,会产生大量的不连续的空间碎片
-
标记-整理算法:不直接对可回收对象进行清理,而是让所有存活的对象向一端移动,然后直接清理掉边界以外的内存,形成一块连续的内存区域。存在时间效率方面的问题。
-
分代收集算法:根据对象的生命周期,将堆分为新生代和老年代,然后根据各个年代的特点采用最适当的手机算法。在新生代中,对象生存期端,每次回收都会有大量的对象死去,可以使用复制算法,老年代里的对象存活率高,没有额外的空间进行分配担保,可以使用标记-整理或标记-清除。
名称 周期 算法 特点 Serial 新生代 复制算法 单线程收集器、STW ParNew 新生代 复制算法 Serial多线程版本 Parallel Scavenge 新生代 复制算法 吞吐量有限 Serial Old 老年代 标记-整理算法 Serial 老年代版本 Parallel old 老年代 标记-整理算法 Parallel Scavenge老年代版本 CMS(Concurrent Mark Sweep) 老年代 标记-清除算法 并发收集、低停顿、产生空间碎片 G1(Garbage First) 老年代 标记-清除和标记-复制算法结合 并行与并发、分代收集、空间整合、可预测停顿
-
-
生产环境是用什么垃圾收集器:新生代的垃圾回收器是ParNewGC,老年代的回收期是ConcurrentMarkSweepGC(CMS,并发标记清除GC)