jvm拥有自己的垃圾回收机制,可以自动进行垃圾回收,释放内存。
定义:通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的。
那么什么可以选做GC Roots”对象呢?
以下四种可以作为GC Roots”对象:
虚拟机栈中引用的对象:引用栈帧中的本地变量表的所有对象
方法去静态属性引用的对象:引用方法区该静态属性的所有对象
方法区常量引用的对象:引用方法区中常量的所有对象
本地方法栈中引用的对象:引用Native方法的所有对象
可达性分析的四种引用类型
1.强引用:
强引用就是指在程序代码之中普遍存在的,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
应用场景:代码中常规声明
例子:Object obj = new Object()
2.软引用
软引用用来描述一些还有用,但并非必需的对象。对于软引用关联着的对象,如果内存充足,则垃圾回收器不会回收该对象,如果内存不够了,就会回收这些对象的内存。
应用场景:软引用主要应用于内存敏感的高速缓存
例子:SoftReference
3.弱引用
引用描述非必需对象。被弱引用关联的对象只能生存到下一次垃圾回收之前,垃圾收集器工作之后,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
应用场景:如ThreadLocal的使用
1.防止内存泄漏,保证内存被JVM回收
2.保护对象引用
例子:WeakReference
4.虚引用
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收的活动。
应用场景:虚引用主要用来跟踪对象被垃圾回收的活动。
例子:
ReferenceQueue
PhantomReference
1.标记-删除算法
简约就是先标记后删除
2.复制算法
简约就是复制可用内存
3.标记-整理算法
简约就是先标记后整理
年轻代有:Serial收集器、 Parnew收集器、Parallel Scavenge收集器(jvm8默认)、G1收集器
老年代有:Serial Old收集器、CMS收集器、Parallel Old收集器(jvm8默认)、G1收集器
Serial收集器:
Serial收集器的两个特点:一个是采用复制算法,另外一个是单线程收集
Parnew收集器:
Parnew收集器的两个特点:一个是采用复制算法,另外一个是多线程收集。
Parallel Scavenge收集器(jvm8默认):
Parallel Scavenge收集器的三个特点:一个是采用复制算法,一个是多线程收集,一个是达到控制吞吐量的目标。
Serial Old收集器:
Serial Old收集器的两个特点:一个是采用标记-整理算法,另外是一个单线程收集。
Parallel Old收集器(jvm8默认):
Parallel Old收集器的两个特点:一个是采用标记-整理算法,另外一个是多线程收集。
CMS收集器:
基本概念:CMS(Concurrent Mark Sweep,并发标记扫描)收集器是以获取最短回收停顿时间为目标的收集器。使用标记-清除算法。
收集步骤:
初始标记:标记 GCRoots 能直接关联到的对象,时间很短;
并发标记:进行 GCRoots Tracing(可达性分析)过程,时间很长;
重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,时间较长;
并发清除:回收内存空间,时间很长。其中,并发标记与并发清除两个阶段耗时最长,但是可以与用户线程并发执行。
优点 :
1.并发收集
2.低延迟
缺点 :
1.会产生内存碎片,导致并发清除后,用户线程可用的空间不足。在无法分配大对象的情况下,不得不提前触发Full GC。
2.CMS收集器对CPU资源非常敏感,在开发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
3.CMS收集器无法处理浮动垃圾,可能出现 “Concurrent Mode Failure” 失败而导致另一次Full GC的产生。在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或者交叉运行的,那么在并发标记阶段如果产生新的垃圾对象,CMS经无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有被及时回收,从而只能在下一次执行GC时释放这些之前未被回收的内存空间。
G1收集器:
基本概念:G1 是目前技术发展的最前沿成果之一,jvm9后默认使用G1回收器。
主要环节 :
G1 GC的垃圾回收过程主要包括如下三个环节:
年轻代GC (Young GC)
老年代并发标记过程(Concurrent Marking)
混合回收(Mixed GC)
(如果需要,单线程、独占式、高强度的Full Gc还是继续存在的。它针对GC的评估失败提供了一种失败保护机制,即强力回收。)
特点:
a.并发和并行:使用多个 CPU 来缩短 Stop The World 停顿时间,与用户线程并发执行;
b.分代收集:独立管理整个堆,但是能够采用不同的方式去处理新创建对象和已经存活了一段时间、熬过多次 GC 的旧对象,以获取更好的收集效果;
c.空间整合:基于标记-整理算法,无内存碎片产生;
d.可预测的停顿:能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集器上的时间不得超过N毫秒。
优点:
G1将内存划分为一个个的region。内存的回收是以region作为基本单位的。Region之间是复制算法,但整体上实际可看作是标记-压缩算法,两种算法都可以避免内存碎片。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。尤其是当Java堆非常大的时候,G1的优势更加明显。
可预测的停顿时间模型(即:软实时soft real-time)
这是G1 相对于CMS 的另一大优势,G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
由于分区的原因,G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。G1 跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。保证了G1 收集器在有限的时间内可以获取尽可能高的收集效率。