JVM 面试题 011 - 020

011、不可达对象非死不可吗?

在可达性分析算法中被判定不可达的对象不一定非死不可,要宣告这个对象死亡,至少需要经历两次标记过程:在进行可达性分析时发现对象不可达,该对象将会被第一次标记;随后会再进行一次筛选,筛选的条件是此对象是否有必要执行 finalize() 方法,假如对象没有覆盖 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过了,那么虚拟机就认为没有必要执行该对象的 finalize() 方法,如果对象被判定有必要执行 finalize() 方法,那么该对象将会被放在一个队列中进行第二次标记,如果这个对象能在执行 finalize() 方法时与引用链上的任何一个对象建立关联,那么它将不会被回收。

012、垃圾收集算法?

1、标记 - 清除算法

该算法首先标记出所有需要回收的对象,标记完成后,统一回收掉所有被标记的对象。

这种算法有两个缺点:其一,执行效率不稳定,如果 Java 堆中包含大量对象,且其中大部分是需要回收的,这是必须进行大量标记和清除的操作,导致标记和清除两个过程的执行效率随对象数量增长而降低;其二,内存空间碎片化严重,标记、清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后程序在分配较大对象时找不到足够的连续空间而不得不提前触发另一次垃圾收集操作。

image-20210217213955001

2、标记 - 复制算法

该算法将可用内存按容量划分为大小相等的两块,每次只是用其中的一块,其中一块内存用完后,就将还活着的对象复制到另一块上面去,然后再把使用过的内存空间一次性清理掉。

这种算法的主要缺点是每次只使用一半的内存,空间浪费太多。

image-20210217214542452

3、标记 - 整理算法

该算法首先标记所有存活的对象,然后让所有存活的对象都向内存空间的一端移动,最后直接清理掉边界以外的内存。

这种算法的主要缺点是,如果每次回收都有大量对象存活,那么移动这些对象并更新所有引用这些对象的地方将会是一种极大地负担,并且这种移动对象的操作必须全程暂停用户应用程序才能进行。

image-20210217215541411

总之,没有完美的算法,我们需要在特定的区域用特定的算法,例如:在新生代,每次都会有大量的对象死去,此时就很适合用标记 - 复制算法,我们只需要付出少量对象的复制成本就可以完成垃圾收集;但是在老年代,几乎每次都有大量对象存活,而且没有额外的空间进行担保,我们必须采用标记 - 清除或标记 - 整理算法来进行垃圾收集

013、Serial 收集器?

Serial 收集器是一个新生代的单线程垃圾收集器,采用标记 - 复制算法,它在进行垃圾收集工作的时候必须暂停其他所有的工作线程(Stop The World),直到它收集结束。

Serial 收集器有没有优于其他垃圾收集器的地方呢?当然有,它简单而高效(与其他收集器的单线程相比),Serial 收集器由于没有线程交互的开销,自然可以获得很高的单线程收集效率,对于客户端模式下的虚拟机来说 Serial 收集器是一个很不错的选择。

image-20210217222207047

014、ParNew 收集器?

ParNew 收集器其实就是 Serial 收集器的多线程并行版本,也是新生代的,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器完全一样。

image-20210217224144902

015、Parallel Scavenge 收集器?

Parallel Scavenge 收集器也是使用标记 - 复制算法的多线程新生代收集器,它看上去几乎和 ParNew 一样,但实际上,Parallel Scavenge 收集器关注点是吞吐量(高效率的利用 CPU),所谓吞吐量就是 CPU 中用于运行用户代码的时间与 CPU 总消耗时间的比值。CMS 等垃圾收集器的关注点更多的是降低用户线程的停顿时间(提高用户体验)。 如果对于收集器运作不太了解,手工优化存在困难的时候,使用 Parallel Scavenge 收集器配合自适应调节策略,把内存管理优化交给虚拟机去完成也是一个不错的选择。

image-20210217225543646

016、Serial Old 收集器?

Serial Old 收集器是 Serial 收集器的老年代版本,它是单线程的,采用的是标记 - 整理算法,在进行垃圾收集工作的时候同样需要暂停所有的工作线程。它主要有两大用途:一种用途是在 JDK1.5 及以前的版本中与 Parallel Scavenge 收集器搭配使用,另一种用途是作为 CMS 收集器发生失败时的后备方案。

image-20210217222207047

017、Parallel Old 收集器?

Parallel Old 是 Parallel Scavenge 收集器的老年代版本,支持多线程并行收集,基于标记 - 整理算法实现。

在注重吞吐量或 CPU 资源较为稀缺的场合,都可以优先考虑 Parallel Scavenge 收集器和 Parallel Old 收集器配合使用。

image-20210217225543646

018、CMS 收集器?

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它采用标记 - 清除算法,用于回收老年代的对象,它是 HotSpot 虚拟机上第一款真正意义上的并发收集器,第一次实现了让垃圾收集线程和用户线程(基本上)同时工作。

它的运作步骤比较复杂,分为四步:

  • 初始标记:暂停所有用户线程(Stop The World),标记 GC Roots 能直接关联到的对象,速度很快。
  • 并发标记:从 GC Roots 的直接关联对象开始遍历整个对象图,这个过程耗时较长但不需要暂停用户线程。
  • 重新标记:该阶段是为了修正并发标记期间,因用户程序运作而导致标记产生变动的那一部分对象的标记记录,这个阶段也需要暂停用户线程,耗时比初始标记阶段稍长,但远比并发标记阶段耗时短。
  • 并发清除:清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,该阶段也可以和用户线程并发进行。

image-20210218155543436

CMS 收集器的主要优点是:并发收集、低停顿,非常适合在注重用户体验的应用上使用。

CMS 收集器的主要缺点是:

  • 对处理器资源非常敏感。在并发阶段它虽然不会导致用户线程停顿,但却因为占用了一部分 CPU 资源而导致应用程序变慢,总吞吐量降低。
  • 无法处理浮动垃圾。在 CMS 的并发标记和并发清理阶段,用户线程还在运行是有可能产生垃圾的,但这些垃圾出现在标记过程结束以后,这些垃圾就是浮动垃圾,CMS 无法在此次收集中回收它们,只能留待下一次再清理掉。
  • 有可能会出现并发失败的情况。由于 CMS 运行期间用户线程也并发执行,为了满足用户线程的执行需要,就必须预留一部分内存空间,如果预留空间过小,无法满足用户线程分配新对象的需要就会导致并发失败,此时虚拟机会启动后备预案:冻结用户线程的执行,临时启用 Serial Old 收集器来进行垃圾收集,但这样停顿时间就很长了。
  • 因为采用标记 - 清除算法,所以会有大量空间碎片产生。

019、G1 收集器?

G1(Garbage First)是一款主要面向服务端应用的垃圾收集器,该收集器同时采用了标记 - 整理算法和标记 - 复制算法,主要针对配备多个处理器及大容量内存的机器,以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量的性能特征。

G1 收集器的目标是能够建立起停顿时间模型,该模型的意思是在一个指定时长为 M 毫秒的时间片内,消耗在垃圾收集上的时间大概率不超过 N 毫秒

为了实现这个目标,G1 在遵循分代收集理论设计的基础上,对堆内存的布局做了很大的改变:G1 不再坚持固定大小以及固定数量的分代区域划分,而是把 Java 堆划分为多个大小相等的独立区域,这个区域被称作 Region,每一个 Region 都可以根据需要,扮演新生代的 Eden 空间、Survivor 空间或老年代空间,收集器能够对扮演不同角色的 Region 采用不同的策略去处理

G1 收集器在后台维护了一个优先级列表,每次根据用户设定得允许收集停顿时间(默认 200 毫秒),优先处理回收价值收益最大的 Region(这也就是它的名字 Garbage-First 的由来) 。这种使用 Region 划分内存空间,以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内获取尽可能高的收集效率。

G1 收集器的运作步骤可以大致分为以下四步:

  • 初始标记:该阶段主要是标记一下 GC Roots 能直接关联到的对象,只需要短暂地停顿用户线程。
  • 并发标记:从 GC Roots 直接关联到的对象开始递归扫描整个堆里的对象图,找出需要回收的对象,该阶段耗时较长,但可与用户线程并发执行,当对象图扫描完后以后,还需要处理一下原始快照(STAB)记录下的在并发时有引用变动的对象。
  • 最终标记:该阶段需要对用户线程进行短暂停顿,用于处理并发标记结束后仍遗留下来的那部分原始快照(STAB)记录。
  • 筛选回收:该阶段会对各个 Region 的回收价值和成本进行排序,然后根据用户期望的停顿时间制定回收计划,最后把决定回收的那一部分 Region 的存活对象复制到空的 Region 中,再清理掉旧 Region 的全部空间,这里的操作涉及存活对象的移动,必须暂停用户线程,然后由多条收集线程并行完成。

image-20210218173206831

020、HotSpot 虚拟机的垃圾收集器?

image-20210218174201364

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值