《剑指Java面试-Offer直通车》--Java底层知识GC

本文详细介绍了Java垃圾收集的标记算法,包括引用计数和可达性分析,以及各种回收算法如复制、标记-清除、标记-整理和分代收集。重点讨论了分代收集算法,解释了年轻代和老年代的特点,以及不同阶段的垃圾收集器,如Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS和G1。此外,文章还探讨了常见的面试问题,如强引用、软引用、弱引用和虚引用的作用。
摘要由CSDN通过智能技术生成

目录

一、标记算法

引用计数算法

可达性分析算法

二、回收算法

标记-清除算法(Mark and Sweep)

复制算法(copying)

标记-整理算法(Compacting)

分代收集算法(Generational Collector)

分代收集算法的GC分类

分代收集算法年轻代

分代收集算法老年代

分代收集算法关键词

三、常见的垃圾收集器

JVM的运行模式

垃圾收集器之间的联系

年轻代常见的垃圾收集器

Serial收集器(-XX:+UseSerialGC,复制算法)

ParNew收集器(-XX:+UseParNewGC,复制算法)

Parallel Scavenge收集器(-XX:+UseParallelGC,复制算法)

老年代常见的垃圾收集器

Serial Old(MSC)收集器(-XX:+UseSerialOldGC,标记-整理算法)

Parallel Old收集器(-XX:+UseParallelOldGC,标记-整理算法)

CMS收集器(-XX:+UseConcMarkSweepGC,标记-清除算法)

G1收集器(-XX:+UseG1GC,复制 + 标记-整理算法)

四、常见面试题

Object的finalize()方法的作用是否与C++的析构函数作用相同?

Java中的强引用、软引用、弱引用、虚引用有什么用?


一、标记算法

对象被判定为垃圾的标准:没有被任何对象引用的情况下,对于系统而言就是垃圾,占据的内存就要被释放,此对象也会被销毁。

判定对象不被引用的方法:1)引用计数算法;2)可达性分析算法

  • 引用计数算法

通过判断对象的引用数量来决定对象是否可以被回收。

堆中的每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。当一个对象被创建的时候,若该对象实例分配一个引用变量,该对象实例的引用计数就设置为1,若该对象又被另外一个对象所引用,则该对象的引用计数器继续+1,而当该对象实例的某个引用超过了生命周期,或者被设置为一个新值的时候,该对象实例的引用计算便会-1。任何引用计数为0的对象实例可以被当作垃圾收集。

优点是执行效率高,程序执行受影响较小。只需过滤出引用计数器为0的对象,将其内存回收即可,可以交织在程序运行中。垃圾回收时可以做到几乎不打断程序的执行,对程序需要不被长时间打断的实时环境比较有利;缺点是实现过于简单,无法检测出循环引用的情况,导致内存泄漏。如父对象引用子对象,子对象引用父对象。

主流的Java垃圾收集器没有采用上述机制判断对象是否为垃圾,而用可达性分析算法对垃圾对象进行标记。

  • 可达性分析算法

通过判断对象的引用链是否可达来决定对象是否可以被回收。可达性算法是从离散数学的图论引入的,程序把所有的引入关系看作一张图,通过一系列名为GC root作为起始点,从这些节点开始向下搜索,搜索所走过的路径就被称为引用链,当一个对象从GC root没有任何引用链相连,从图论上来说就是从GC root到这个对象是不可达的,这个时候就证明了这个对象是不可用的,它就被标记为垃圾了。

 可以作为GC Root的对象

1)虚拟机栈中引用的对象(栈帧中的本地变量表中引用的对象)

2)方法区中的常量引用的对象。比如,类里面定义的常量,该常量保存的某个对象的地址,那么被保存的对象也称为GC的根对象,当别的对象引用到它的时候就会形成关系链

3)方法区中的类静态属性引用的对象

4)本地方法栈中JNI(Native方法)的引用对象

5)活跃线程的引用对象

 

二、回收算法

  • 标记-清除算法(Mark and Sweep)

1)标记:从根集合进行扫描,对存活的对象进行标记,使用的是可达性算法来找到垃圾对象。

2)清除:标记完成后,对堆内存从头到尾进行线性遍历,如果发现对象没有被标识为可达对象,就将此对象占用的内存回收,并且将之前标记为可达的标识清除掉以便进行下一次垃圾回收,回收不可达对象内存。


标记-清除算法缺点:产生大量碎片化。由于标记清除不需要对象的移动,并且仅对不存活的对象进行处理,因此标记清除之后,会产生大量不连续的内存碎片,空间碎片太多,可能会导致以后在程序运行过程中,需要分配较大的对象时,无法找到足够的连续内存,而不得不提前触发另一次垃圾收集动作。

  • 复制算法(copying)

分为对象面和空闲面。复制算法将可用的内存按照容量和一定比例划分为两块或者多个块,并选择其中一块或者两块作为对象面,其他的作为空闲面。

对象则是在对象面上创建的。当被定义为对象面的块的内存使用完之后,就将还存活着的对象复制到其中一块空闲面上。

将对象面所有对象内存清除。将已使用过的内存空间一次清理掉。

复制算法优点:复制算法解决碎片化的问题。顺序分配内存,简单高效。适用于对象存活率低的场景,如年轻代。

  • 标记-整理算法(Compacting)

适用于老年代的对象回收。采用标记清除算法一样的对象标记,但在清除时有所不同。

1)标记:从根集合进行扫描,对存活的对象进行标记。

2)清除:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。

标记-整理算法是在标记-清除算法的基础上又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。

标记-整理算法优点:避免内存的不连续性。不用设置两块内存互换。适用于对象存活率极高的场景,如老年代的回收。

  • 分代收集算法(Generational Collector)

主流的垃圾回收算法。垃圾回收算法的组合拳。按照对象生命周期的不同划分区域以采用不同的垃圾回收算法(将堆内存进行进一步划分,不同的对象的生命周期以及存活情况是不一样的,将不同生命周期的对象分配到堆中不同的区域,并对堆内存不同区域采用不同的策略进行回收)。分代收集算法目的,提高JVM垃圾回收执行效率。

 JDK6、JDK7的堆内存,分为年轻代(Young Generation)、老年代(Old Generation)、永久代(Permanent Generation)。


JDK8及其以后的版本,堆内存分为年轻代(Young Generation)、老年代(Old Generation)。年轻代的对象存活率低就会采用复制算法,老年代对象存活率高,就会采用标记-清除算法或者标记-整理算法。

  • 分代收集算法的GC分类

1)Minor GC:发生在年轻代中的垃圾收集动作,采用的复制算法。年轻代是几乎所有Java对象出生的地方,即Java对象申请的内存以及存放都是在年轻代的。Java中的大部分对象不需要长久的存活,具有朝生夕灭的性质。当一个对象被判断为死亡的时候,GC就有责任回收掉这部分对象的内存空间。新生代是GC收集垃圾的频繁区域。

2)Full GC:这种GC和老年代相关,由于对老年代的回收一般会伴随着年轻代的垃圾收集,因此,此种方式称为Full GC。

  • 分代收集算法年轻代

尽可能快速的收集掉那些生命周期短的对象。

1)Eden区:伊甸园,人类的起源。对象刚被创建出来时,其内存空间首先是被分配在Eden区的,如若Eden区放不下新创建的对象的时候,对象也有可能直接放到Survivor区,甚至是老年代中。

2)两个Survivor区:分别被定义为from区和to区,哪个是from区,哪个是to区也不是固定的,会随着垃圾回收的进行而相互转换,年轻代的目标就是尽可能快速收集掉那些生命周期较短的对象。一般情况下,所有新生成的对象首先都是放在年轻代的。

年轻代内存会按照8:1:1的默认比例划分为Eden区和两个Survivor区,绝大部分对象是在Eden区生成。新生代中98%的对象都是朝生夕死的,所以不需要按照1:1:1的比例来划分内存空间,而是将年轻代内存分为一块较大的Eden区和两块较小的Survivor区,每次使用Eden和其中的一块Survivor区。当进行垃圾回收的时候,将Eden和Survivor区存活的对象一次性复制到另一块Survivor区,最后清理掉Eden区和用过的Survivor区。当Survivor区空间不够用的时候,则需要依赖老年代,进行分配的担保。

eg:

暂且忽略Eden区和Survivor区的默认比例,并且假设每个对象的大小都是一样的。Eden区最多能保存4个对象,Survivor区最多能保存3个对象。

当程序开始运行时,若对象在Eden区出生并且被挤满会触发一次Minor GC,此时如果对象还存活,就会被复制到其中一块Survivor区中。假设复制到S0,S0就称为from区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值