垃圾回收是一种自动的存储管理机制。 当一些被占用的内存不再需要时,就应该予以释放,以让出空间,这种存储资源管理,称为垃圾回收(Garbage Collection)。 垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会。
GC触发的条件有两种: (1)程序调用System.gc时可以触发; (2)系统自身来决定GC触发的时机。
了解jvm内存结构
Minor GC触发条件:当Eden区满时,触发Minor GC。
Full GC触发条件:
自动垃圾回收机制就是寻找Java堆中的对象,并对对象进行分类判别,寻找出正在使用的对象和已经不会使用的对象,然后把那些不会使用的对象从堆上清除。如何区别这两类对象呢?这就有了两种方式:
引用计数法
引用计数算法是垃圾收集器中的早期策略。 在这种方法中,堆中的每个对象实例都有一个引用计数。当一个对象被创建时,且将该对象实例分配给一个引用变量,该对象实例的引用计数设置为 1。当任何其它变量被赋值为这个对象的引用时,对象实例的引用计数加 1(a = b,则b引用的对象实例的计数器加1),但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数减 1。
特别地,当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器均减 1。 任何引用计数为0的对象实例可以被当作垃圾收集。
引用计数收集器可以很快的执行,并且交织在程序运行中,对程序需要不被长时间打断的实时环境比较有利,但其很难解决对象之间相互循环引用的问题。
可达性分析
可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过一系列的名为 “GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。 当一个对象到 GC Roots 没有任何引用链相连(用图论的话来说就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的。
在java中可以作为GC roots的有四种
1.Serial(串行GC)收集器
Serial收集器是一个新生代收集器,单线程执行,使用复制算法。它在进行垃圾收集时,必须暂停其他所有的工作线程(用户线程)。是Jvm client 模式下默认的新生代收集器。对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率
2.ParNew(并行GC)收集器
ParNew 收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial收集器一样。
3. ParallelScavenge收集器
是一个新生代收集器,它也是使用复制算法的收集器,又是并行多线程收集器。Parallel Scavenge 收集器的特点是它的关注点与其他收集器不同, CMS等收集器的关注点是尽可能的缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标是达到一个可控制的吞吐量。 吞吐量=程序运行时间/(程序运行时间+垃圾收集时间)、虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%
4. SerialOld (串行GC)收集器
Serial Old是Serial收集器的老年代版本,它同样使用一个单线程执行收集、使用“标记-整理”算法。主要使用在Client模式下的虚拟机。
5.ParallelOld(并行GC)收集器
Serial Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法
6. CMS(Concurrent Mark Sweep)收集器是一种获取最短回收停顿时间为目标的收集器
初始标记、并发标记、重新标记、并发清除
7.G1收集器
初始标记、并发标记、最终标记、筛选回收
1.强引用:使用new关键字创建的引用,只要强引用还存在,则垃圾回收永远不会回收掉被引用的对象
2.软引用:描述还有用但是非必须的对象,在系统即将发生内存溢出的时候才将这些对象放到回收范围中进行二次回收,如果回收之后还没有足够内存,则出现内存溢出异常。
3.弱引用:用来描述非必须的对象,但是它比软引用要弱一些,当垃圾回收期工作时,无论内存是否够用都会将引用的对象回收掉
4.虚引用:它是最弱的一种引用关系,对象是否有虚引用不会影响其生命周期,虚引用的唯一目的就是能在这个对象被回收是收到一个系统通知
原文:https://www.cnblogs.com/jiezao/p/13334037.html