JVM调优的原理和调优关键分析

是这样的,想请问下,JVM调优的原理和调优关键分析
最新回答
你模仿不起

2026-02-10 16:57:56

JVM调优的原理和调优关键分析

一、JVM的GC基本原理

  1. 什么是垃圾?

    在内存中没有被引用的对象就是垃圾。一次请求会在内存中创建出很多对象,这些对象不会自己消失,必须进行垃圾回收,垃圾回收器是JVM自己提供的。

    特别注意:高并发的场景下,内存中尤其会创建海量的对象,这些对象所占用的内存必须及时被释放,否则会影响程序性能。

  2. 如何找到垃圾?

    JVM中有两种寻找垃圾对象的方案:引用计数算法和根可达算法(hotspot垃圾回收器使用此算法)。

    引用计数算法:

    通过引用计数方法找到垃圾。当一个对象引用都消失了,计数就会变为0,此时这个对象就会变成垃圾。

    存在问题:引用计数算法不能解决循环引用问题。

    根可达算法:

    hotspot目前使用的主要的垃圾回收器的算法,因为引用计数无法解决循环引用计数的问题。

    基本思想:通过一系列名为“GC roots”的对象作为起始点,从这个被称为GC roots的对象开始,向下搜索,如果一个对象到GC roots没有任何引用链相连时,说明此对象不可用。

    GC roots对象起始点,或者说tracing GC的“根集合”就是一组必须活跃的引用。

  3. 如何清除垃圾?

    JVM提供三种方法清除垃圾对象:Mark-Sweep标记清除算法、Copying拷贝算法、Mark-Compact标记压缩算法。

    Mark-Sweep标记清除算法:

    缺点:内存存储空间碎片化。

    Copying拷贝算法:

    原理:为了解决效率问题,Copying拷贝算法将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

    优点:没有碎片化,所有的有用的空间都连接在一起,所有的空闲空间都连接在一起。

    缺点:存在空间浪费。

    Mark-Compact标记压缩算法:

    原理:标记压缩算法把存活对象拷贝到可回收的空间,然后把存活对象空间进行压缩,串联起来,把未使用的对象空间串联起来,组成连续的内存空间,这样就不会有碎片。

    缺点:性能较低,因为除了拷贝对象以外,还需要对象内存空间进行压缩。

  4. 用什么清除垃圾?

    有7种不同的垃圾回收器,它们分别用于不同分代的垃圾回收:

    新生代回收器:Serial、ParNew、Parallel Scavenge

    老年代回收器:Serial Old、Parallel Old、CMS

    整堆回收器:G1

    两个垃圾回收器之间有连线表示它们可以搭配使用,常见的搭配方案包括:

    Serial + Serial Old

    Serial + CMS

    ParNew + Serial Old

    ParNew + CMS

    Parallel Scavenge + Serial Old

    Parallel Scavenge + Parallel Old

    G1 + G1

二、调优关键指标

  1. 吞吐量

    重要指标之一,吞吐量是衡量系统在单位时间里面完成的工作数量。

    吞吐量需求通常忽略延迟或者响应时间。

    通常情况下,提升吞吐量需要以系统响应变慢和更多内存消耗作为代价。

    衡量指标:

    TPS:每秒事务数

    吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

  2. 延迟或响应时间

    延迟或者响应时间是衡量应用从接收到一个任务到完成这个任务消耗的时间。

    一个延迟或者响应时间的需求需要忽略吞吐量。

    通常来讲,提升应用的响应时间需要以更低吞吐量或提高应用的内存消耗为代价。

  3. 内存占用

    内存占用是衡量应用消耗的内存,这个内存占用是指应用在运行在某一个吞吐量、延迟以及可用性和易管理性指标下的内存消耗。

    内存占用通常描述为应用运行的时候Java堆的大小或者总共需要消耗内存。

    通常情况下,通过增加Java堆的大小以增加应用内存占用可以提升吞吐量或者减少延迟,或者两者兼具。

    当应用可用的内存减少的时候,吞吐量和延迟通常会受到损失。

    在给定内存的情况下,应用占用的内存可以限制应用的实例数(这会影响可用性)。

综上所述,JVM调优的原理主要基于垃圾回收算法和垃圾回收器的选择,而调优的关键指标则包括吞吐量、延迟或响应时间以及内存占用。在进行JVM调优时,需要综合考虑这些指标,并根据实际应用场景和需求进行权衡和优化。