JVM调优篇:探索Java性能优化的必备种子面试题(下)

picture.image

/ JVM 有哪些垃圾回收算法 /

MarkSweep:标记清除算法,目的是将垃圾标记后,直接清楚垃圾,这样会导致产生过多的内存碎片,当分配大对象时,可能会导致 full gc,又或者直接内存溢出。

picture.image

Copying:拷贝算法,拷贝算法(Copying)牺牲了一半的内存空间,只使用其中一半进行分配。在标记存活对象后,将对象整体迁移至另一半内存空间,减少内存碎片,但牺牲了可使用空间。

picture.image

MarkCompack:标记压缩算法,为了解决拷贝算法的缺陷,就提出了标记压缩算法。这种算法在标记阶段跟标记清除算法是一样的,但是在完成标记之后,不是直接清理垃圾内存,而是将存活对象往一端移动,然后将端边界以外的所有内存直接清除。

picture.image

/ JVM 有哪些垃圾回收器? /

picture.image

Serial: 单线程垃圾回收器,使用复制算法。主要适用于小型应用程序和单核处理器。

picture.image

Serial Old: 老年代单线程垃圾回收器,使用标记-整理算法。适用于较小的应用程序和单核处理器,对于大型应用程序可能会导致停顿时间较长。

ParNew: 年轻代多线程垃圾回收器,使用复制算法。与 Serial 相比,ParNew 可以利用多个线程进行垃圾回收,提高回收效率。

picture.image

Parallel Scavenge: 年轻代多线程垃圾回收器,使用复制算法。目标是尽可能地减少垃圾收集的停顿时间,适用于对系统吞吐量要求较高的应用程序。

picture.image

Parallel Old: 老年代多线程垃圾回收器,使用标记整理算法。与 Serial Old 相比,Parallel Old 可以利用多个线程进行垃圾回收,提高回收效率。

CMS: 老年代多线程并发垃圾回收器,默认使用标记清除算法,可配置标记整理算法。CMS 的目标是减少垃圾收集的停顿时间,适用于对响应时间要求较高的应用程序。

picture.image

G1: 基于分代的垃圾回收器,已去除物理上的年轻代和老年代概念。使用 region 块来保存和分配内存,整体上使用标记整理算法,微观上使用复制算法。G1 的目标是在有限的时间内获得可控制的停顿时间,适用于大型应用程序和对响应时间要求较高的应用程序。

picture.image

1

什么是 STW

STW(Stop The World)是指在垃圾回收过程中,所有应用程序的线程都会被暂停,只有垃圾回收线程在执行垃圾回收操作。这意味着在 STW 期间,应用程序无法继续执行任何任务,可能会导致一些延迟和性能问题。

减少 STW 时间是垃圾回收优化的一个重要目标。JVM 的垃圾回收器会不断进行优化,以减少 STW 时间,使应用程序的暂停时间尽可能短。不同的垃圾回收器有不同的优化策略和算法,以满足不同场景下的需求。

2

STW 都发生在那些阶段

抛开单线程和多线程单一停顿时间不看,只看下 CMS 和 G1 垃圾回收器

CMS:共分为初始标记,并发标记,重新标记,并发回收四个阶段;其中初始标记和重新标记将会进行 STW,但是拉开了 STW 的战线,所以总的停顿时间缩小了,但是由于他是在跟工作线程同时进行回收,所以肯定会产生浮动垃圾;picture.image

G1:共分为初始标记,并发标记,重新标记,筛选回收四个阶段;和 CMS 逻辑相同,但是筛选回收将会进行计算,jvm 会判断回收成本并执行回收计划,来优先回收哪些对象

picture.image

3

三色标记

三色标记是指将对象分为三个不同的颜色:白色、灰色和黑色。是 CMS(Concurrent Mark Sweep)的标记算法

  • 白色:表示对象未被访问过,也就是未被标记为存活对象。

  • 灰色:表示对象已经被访问过,但它引用的其他对象还未被标记。

  • 黑色:表示对象已经被访问过,并且它引用的其他对象也都被标记。

在并行标记阶段,CMS 会先将根节点标记为灰色,然后并行地遍历对象引用,将引用的对象标记为灰色,并将其加入标记队列。当标记队列为空时,标记阶段结束。

然而,由于并行标记与应用程序执行是同时进行的,可能会导致在标记阶段结束后,仍然存在引用发生变化的情况,比如引用删除或引用转变。为了解决这个问题,CMS 需要进行重新标记的过程。重新标记会遍历所有的灰色对象,并将它们标记为黑色。这样可以确保所有的引用关系都被正确地标记,并且不会错误地回收正在使用的对象。

/ 如何进行 JVM 调优 /

JVM 调优主要就是通过定制 JVM 运行参数来提高 JAVA 应用程度的运行数据

4

JVM 参数有哪些

JVM 参数大致可以分为三类:

  • 标注指令:-开头,这些是所有的 HotSpot 都支持的参数。可以用 java -help 打印出来。

  • 非标准指令:-X 开头,这些指令通常是跟特定的 HotSpot 版本对应的。可以用 java -X 打印出来。

  • 不稳定参数:-XX 开头,这一类参数是跟特定 HotSpot 版本对应的,并且变化非常大。详细的文档资料非常少。在 JDK1.8 版本下,有几个常用的不稳定指令:

  1. java -XX:+PrintCommandLineFlags :查看当前命令的不稳定指令。

  2. java -XX:+PrintFlagsInitial :查看所有不稳定指令的默认值。

  3. java -XX:+PrintFlagsFinal:查看所有不稳定指令最终生效的实际值

5

JVM 调优的开发者工具

JVM 调优通常需要借助一些开发者工具来辅助。阿里开源的 Arthas 就是一款非常强大的 Java 诊断工具,它可以帮助开发人员进行实时的性能分析和问题排查。

Arthas 具有丰富的功能,比如查看 Java 虚拟机的运行状态、监控方法执行时的参数和返回值、查看线程状态和运行时间、查看类加载和字节码等。它还支持在运行时修改类的方法体和实例状态,以及记录方法调用堆栈等功能。

使用 Arthas,开发人员可以方便地发现性能瓶颈和问题,并进行针对性的优化。它在 Java 开发中非常受欢迎,尤其是在分布式系统和微服务架构中的性能调优中发挥了重要作用。

当然,除了 Arthas,还有其他一些常用的 JVM 调优工具,比如 VisualVM、JConsole、JProfiler 等,开发人员可以根据自己的需要选择适合自己的工具来进行 JVM 调优。

官方文档地址: https://arthas.aliyun.com/doc/

/ 总结 /

JVM 调优确实不像开发中常见的可视化界面工具那样直观,而更多地需要基于底层的知识和经验来解决问题。JVM 调优的确没有固定的定性规则,但可以根据一些常见的性能问题和优化思路来进行思考和回答。

在面试时,如果遇到 JVM 调优相关的问题,可以按照以下思路来回答:

  • 首先,了解 JVM 的基本架构和垃圾回收机制。这包括堆、栈、方法区等内存结构,以及各种垃圾回收器的特点和工作原理。

  • 掌握常见的性能问题和优化手段。例如,内存泄漏、频繁的 Full GC、长时间的 STW 等问题,可以结合具体情况提出相应的解决方案。

  • 熟悉一些性能监控和分析工具。如前面提到的 Arthas、VisualVM、JConsole 等,可以介绍自己使用过的工具,并举例说明如何利用这些工具进行性能分析和问题排查。

  • 强调实践经验和解决问题的思路。虽然没有固定的定性规则,但可以根据自己的实践经验和理解,提出一些常见的优化思路和原则,比如减少对象的创建和销毁、合理配置内存参数、优化算法和数据结构等。

总之,在回答 JVM 调优相关的面试题时,除了记住一些常见的问题和解决方案,更重要的是展示出自己的思考和解决问题的能力。

0
0
0
0
评论
未登录
暂无评论