Java面试题——第十篇

1. 什么是Java的PLAB

PLAB是Java垃圾回收器中的一种优化机制,主要用于G1垃圾收集器,目的是提高对象晋升到老年代的效率。

在垃圾回收过程中,新生代中的某些对象由于生命周期较长,会被晋升到老年代。为了减少线程竞争和提升晋升效率。G1为每个GC线程分配一个局部缓冲区,称为 PLAB。每个线程可以在其本地PLAB中直接进行对象晋升操作。而不需要竞争全局老年代的内存空间,减少了锁竞争,提高了多线程垃圾回收的效率。

在多线程并行执行YGC时,可能有很多对象需要晋升到老年代,此时老年代的指针就“热”起来了,于是搞了个PLAB。

每个 GC线程先从老年代申请一块空间,然后单个线程在这一块空间中就可以通过指针加法来分配内存,这样对freelist竞争就少了,分配空间也更快。

2. JVM垃圾回收时产生的concurrent mode failure的原因是什么

concurrent mode failure是在Java虚拟机使用 CMS垃圾收集器 时的一种失败现象。当CMS在执行垃圾回收时,发现内存中的老年代空间不足以继续分配新对象时,导致垃圾回收被迫转为Full GC。

产生的原因

  • CMS收集器是并发进行的,意味着他会与应用线程同时运行。然而,如果 在CMS的并发回收阶段,还没有及时清理出足够的空间来满足新对象分配,就会出现concurrent mode failure。
  • 一旦发生concurrent mode failure,JVM会停止应用线程,进入Full GC以回收更多内存,影响程序性能。

1. CMS 垃圾收集器工作原理

  • 初始标记:标记与根对象直接关联的对象,需要短暂停顿。
  • 并发标记:与应用程序并发运行,标记老年代中的存活对象。
  • 重新标记:修正并发标记期间发生变化的对象,再次短暂停顿。
  • 并发清理:清除未被标记的垃圾对象,与应用线程并发运行。

2. concurrent mode failure的优化措施

  • 增大老年代内存:通过增加老年代的堆大小来减少CMS的触发频率,从而避免老年代内存不足。
  • 调优CMS的触发阈值:适当提前触发垃圾回收可以减少发生concurrent mode failure的概率。
  • 碎片整理:CMS不会自动整理碎片,可以通过配置 -XX:UseCMSCompactAtFullCollection 在Full GC后进行碎片整理,避免碎片化导致内存不足的问题。
  • 增加年轻代大小:通过增加年轻代的大小,减少对象频繁晋升到老年代,进而减少老年代的内存压力。

3. Java的G1垃圾回收流程

G1从大局上看分为两大阶段,分别是 并发标记和对象拷贝

并发标记

并发标记是基于STAB的,可以分为四大阶段:

  1. 初始标记:这个阶段是STW的,扫描根集合,标记根直接可达的对象即可。在G1中标记对象是利用外部的bitmap来记录的,而不是对象头。
  2. 并发阶段:这个阶段和应用线程并发,从上一步标记的根直接可达对象开始进行tracing,递归扫描所有可达对象
  3. 最终标记:这个阶段是STW的
  4. 清理阶段:这个阶段是STW的,根据标记的bitmap统计每个region存活对象的多少,如果有完全没存活的region则整体回收。

对象拷贝阶段

这个阶段是STW的。根据标记结果选择合适的region组成收集集合(Cset),然后将Cset存活对象拷贝到新的region中。G1瓶颈在于对象拷贝阶段,需要花较多的瓶颈来转移对象。

4. Java的CMS垃圾回收流程

  1. 初始标记:在这个阶段,CMS会进行一个快速的初始标记,标记所有根对象直接可达的对象,此过程是STW的,但时间较短。
  2. 并发标记:初始标记后,CMS进入并发标记阶段,在这个阶段,垃圾收集器和应用线程并发运行,从上一步标记的根直接可达对象开始进行tracing,递归扫描所有可达对象,此阶段会持续较长时间。
  3. 重新标记:这个阶段是STW的,因为,并发阶段引用关系会发生变化,所以要重新遍历一遍新生代对象、Gc Roots、来修正标记。
  4. 并发清理:CMS进行并发清除,标记为不可达的对象会被清除。

5. Java中的ZGC

ZGC是Java11引入的低延迟垃圾回收器,旨在支持大内存(可以高达数TB)的应用程序,并保持短的GC停顿时间。

主要特点:

  • 并发收集:ZGC的收集过程大部分是在应用线程运行的同时进行,最大限度的减少了停顿时间。
  • 指针压缩:使用指针压缩技术,减少内存占用并提高性能。
  • 无停顿:GC的停顿时间通常在毫秒级,对于大多数应用来说几乎不可察觉。

工作机制:

  • 分代收集:ZGC采用分代的方式管理内存,包括年轻代和老年代。
  • 记录和重标记:通过记忆集跟踪对象的引用关系,以便在GC过程中快速识别存活对象。

6. JVM垃圾回收调优的主要目标是什么

分别是 最短暂停时间高吞吐量

  • 最短停顿时间(停顿时间足够短):垃圾回收调优的首要目标是减少应用程序的停顿时间,确保在垃圾回收过程中尽量保持应用的响应能力,特别是对于实时或者高并发应用。
  • 高吞吐量(停顿频率足够低):第二个目标是提高应用的吞吐量,即在单位时间内完成更多的业务处理,通过合理的GC策略和配置,减少GC的频率和时间,从而提升整体性能。

7. 如何对Java垃圾回收进行调优

GC调优的核心思路是尽可能的使对象在年轻代被回收,减少对象进入老年代

8. 常见JVM参数

-Xms : 初始堆大小
-Xmx:最大堆大小
-Xss:设置每个线程的栈大小
-XX:MetaspaceSize: 初始化元空间大小
-XX:MaxMetaSpaceSize:最大元空间大小
-XX:+HeapDumpOnOutOfMemoryError:当发生outofMemory时,生成堆转储
-XX:+PrintGcDetails: 打印详细的垃圾回收日志
-XX:+UseG1GC:启用G1垃圾回收器

9. 常用哪些工具分析JVM性能

  • jmap:用于生成堆转储的工具,可以用于分析JVM内存使用情况,尤其是内存泄漏问题
  • jstack:用于生成线程转储的工具,可以用于分析线程状态,排查死锁
  • jstat:用于监控JVM统计信息的命令行工具,提供实时的性能数据,如类加载、垃圾回收、编译器等信息。
  • mat:用于分析堆转储文件的工具,可以帮助识别内存泄漏,优化内存使用
  • jconsole:可以监控JVM内存使用、垃圾回收、线程、类加载等信息
  • VisualVM:可实时显示JVM的内存使用、垃圾回收、类加载等信息,也可以分析HeapDump。
  • Arthas:一个强大的Java诊断工具,提供了实时监控和分析功能。可以查看JVM状态、监控方法调用、追踪SQL查询、分析性能瓶颈。

10. 如何在Java中进行内存泄漏分析

  • 利用jstat命令观察gc概要信息,如果发现gc后内存并没有明显的减少且还是持续触发gc,那说明内存泄漏的概率很大
  • 利用jmap生成heap dump,然后将其导入mat或者visualvm工具内进行分析,通过大量内存的占用可以找到对应的对象。
  • 通过对象找到对应的代码分析,确认是否可能存在内存泄漏的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值