JDK 17 微服务启动JVM参数调优实战
JDK 17 微服务启动JVM参数调优实战
- 1.1 POD限制内存4G 时适用的JVM参数配置
- 1.2 POD限制内存8G 时适用的JVM参数配置
1.1 POD限制内存4G 时适用的JVM参数配置
展示版:
-Xmx2g
-Xms2g
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m
-Xss256k
-XX:+UseG1GC
-XX:+AlwaysPreTouch
-XX:-ResizePLAB
-XX:+ParallelRefProcEnabled
-XX:+ExplicitGCInvokesConcurrent
-XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads=4
-XX:ConcGCThreads=2
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.math=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/java.security=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/jdk.internal.access=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
-Duser.timezone=Asia/Shanghai
以下是提供的 JVM 参数的详细解释:
-Xmx2g
含义:设置 JVM 的最大堆内存大小为2GB。堆内存是 JVM 中分配对象的主要区域,当超过这个大小时,会触发 OutOfMemoryError。
推荐用途:根据应用程序的需求设置最大堆内存大小。设置适当的大小以保证应用稳定运行,并避免内存不足。-Xms2g
含义:设置 JVM 的初始堆内存大小为 2GB。JVM 启动时即分配这部分内存。
推荐用途:通常建议 -Xms 和 -Xmx 设置相同的值,避免动态调整堆内存,减少性能开销。-XX:MetaspaceSize=256m
含义:设置初始元空间(Metaspace)的大小为 256MB。元空间用于存储类的元数据,如类的字节码、方法、字段信息等。
推荐用途:可以根据应用程序中类加载的复杂度设置此值。对于简单应用,较低值即可,但如果类较多,适当增加。-XX:MaxMetaspaceSize=256m
含义:设置最大元空间的大小为 256MB。当元空间使用量达到这个值时,JVM 将进行 Full GC 回收未使用的类元数据。
推荐用途:如果应用需要加载大量类,应该增加此值。设置较小值会频繁触发 Full GC,影响性能。-Xss256k
含义:设置每个线程的栈大小为 256KB。线程栈用于存储线程的本地变量、方法调用等。
推荐用途:通常可以设置为 256k 或 512k。如果应用创建大量线程并且栈深度较浅(递归或方法调用链较短),可以使用较小值来节省内存。-XX:+UseG1GC
含义:启用 G1 垃圾收集器,这是 JDK 17 的默认 GC。G1 是一种并发的、低暂停时间的垃圾收集器,适用于大内存、高吞吐量的应用。
推荐用途:适用于大部分现代应用程序,特别是需要低暂停时间的场景。G1 GC 提供了良好的平衡性能。-XX:+AlwaysPreTouch
含义:JVM 在启动时预先分配并 “触碰” 堆内存页。这可以避免在运行过程中进行动态分配和内存页的懒加载。
推荐用途:建议在堆内存较大且想减少内存分配延迟的场景下使用。它在应用启动时可能稍微增加启动时间,但能保证运行中的一致性能。-XX:-ResizePLAB
含义:禁用 PLAB(Promotion Local Allocation Buffers)的动态调整。PLAB 是在垃圾收集过程中,年轻代对象提升到老年代时使用的内存区域。
推荐用途:通常 JVM 自动调整 PLAB 大小。如果手动禁用,则可能影响对象提升效率,这个参数应在特定场景下根据 GC 日志分析后谨慎使用。-XX:+ParallelRefProcEnabled
含义:启用并行处理引用类型(如 SoftReference、WeakReference、PhantomReference)的清理工作。这在垃圾收集过程中可以提高引用类型的处理效率。
推荐用途:在有大量引用对象的应用中,建议启用,以减少 GC 暂停时间。-XX:+ExplicitGCInvokesConcurrent
含义:当调用 System.gc() 时,启用并发的垃圾收集而非 Full GC。这样可以避免 System.gc() 导致长时间的暂停。
推荐用途:如果代码中显式调用了 System.gc(),启用此参数可以降低其对性能的负面影响,推荐在需要控制 System.gc() 行为的应用中使用。-XX:MaxGCPauseMillis=200
含义:设置 G1 垃圾收集器的最大暂停时间目标为 200 毫秒。G1 GC 会尝试在这个时间范围内完成 GC 周期。 推荐用途:对于需要低延迟的应用程序,建议设置合理的目标值,典型值为 100-500
毫秒。根据应用程序的延迟要求调整。-XX:ParallelGCThreads=4
含义:设置并行 GC 线程数为 4。此参数控制了垃圾收集器使用多少线程来执行并行 GC 任务,如对象清理和压缩。
推荐用途:通常设置为 CPU 核心数的数量。对于拥有 4 个核心的 CPU,可以将此值设为 4,保证并行 GC 的性能。-XX:ConcGCThreads=2
含义:设置并发 GC 线程数为 2。这个参数控制 G1 GC 在后台标记和清理垃圾时使用的线程数。
推荐用途:通常设置为 CPU 核心数的 1/4 左右。根据 CPU 核心数和应用的并发性能要求调整。
JDK17为了加快启动速度,支持了模块化编程,默认某些模块不开启需要哪个开启哪个,但是可能我们某些框架无法正常运行,比如反射包等一些包,因此需要手动开启模块:
复制粘贴版:
-Xms2G -Xmx2G -XX:MaxDirectMemorySize=2G -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseG1GC -XX:+AlwaysPreTouch -XX:-ResizePLAB -XX:+ParallelRefProcEnabled -XX:+ExplicitGCInvokesConcurrent -XX:MaxGCPauseMillis=50 -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=10 -XX:InitiatingHeapOccupancyPercent=45 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-exports java.base/sun.net.util=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-exports java.base/sun.net.util=ALL-UNNAMED --add-exports java.base/sun.net.util=ALL-UNNAMED --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -Duser.timezone=Asia/Shanghai
1.2 POD限制内存8G 时适用的JVM参数配置
展示版:
-Xms4G
-Xmx4G
-XX:MaxDirectMemorySize=2G
-XX:MetaspaceSize=128M
-XX:MaxMetaspaceSize=512M
-XX:+UseG1GC
-XX:+AlwaysPreTouch
-XX:-ResizePLAB
-XX:+ParallelRefProcEnabled
-XX:+ExplicitGCInvokesConcurrent
-XX:MaxGCPauseMillis=100
-XX:+UseStringDeduplication
-XX:+UnlockExperimentalVMOptions
-XX:G1NewSizePercent=10
-XX:InitiatingHeapOccupancyPercent=60
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.math=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/java.security=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/jdk.internal.access=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-exports java.base/sun.net.util=ALL-UNNAMED
--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
-Duser.timezone=Asia/Shanghai
以下是提供的 JVM 参数的详细解释:
-Xms4G
含义:设置 JVM 的初始堆内存大小为 4GB。JVM 启动时就分配这部分内存。
推荐用途:通过设置初始堆大小,可以避免在应用运行时进行动态内存扩展,提升性能。通常建议将初始堆大小与最大堆大小 (-Xmx) 设置为相同。-Xmx4G
含义:设置 JVM 最大堆内存大小为 4GB。堆内存是 JVM 中分配对象的主要区域,当超过这个值时,会触发 OutOfMemoryError。
推荐用途:根据应用的内存需求设置最大堆内存大小。与 -Xms 设置为相同值可以避免堆大小频繁调整。-XX:MaxDirectMemorySize=2G
含义:设置最大直接内存(Direct Memory)大小为 2GB。直接内存是 JVM 中堆外内存的一部分,通常用于 ByteBuffer 进行 I/O 操作。
推荐用途:如果应用程序使用了大量的 NIO(非阻塞 I/O)操作,设置较大的直接内存非常重要。根据应用的需求设置合理的值。-XX:MetaspaceSize=256M
含义:设置元空间(Metaspace)的初始大小为 128MB。元空间用于存储类的元数据,如类的字节码和方法信息。
推荐用途:根据应用中加载的类的数量,设置合适的元空间初始大小。对于大量动态类加载的应用程序,可能需要增加该值。-XX:MaxMetaspaceSize=256M
含义:设置最大元空间大小为 512MB。元空间使用量达到该值时,会触发 Full GC 以回收未使用的类元数据。
推荐用途:如果应用中需要加载大量类,适当增加此值以避免频繁的 Full GC。-XX:+UseG1GC
含义:启用 G1 垃圾收集器,这是 JDK 17 的默认垃圾回收器。G1 设计用于大堆内存并提供低暂停时间的垃圾收集。
推荐用途:G1 GC 适合大内存、并发的应用程序,是推荐的垃圾回收器,可以根据应用的需要调整一些参数来优化性能。-XX:+AlwaysPreTouch
含义:JVM 启动时预先分配并“触碰”所有的堆内存。这样在运行过程中无需动态分配内存页,减少运行时的内存分配延迟。
推荐用途:通常在内存较大的应用中使用,确保 JVM 启动后性能稳定,但会导致启动时间略长。-XX:-ResizePLAB
含义:禁用 PLAB(Promotion Local Allocation Buffers)的动态调整。PLAB 是用来在 GC 时从年轻代晋升对象到老年代时的分配缓冲区。
推荐用途:通常建议 JVM 自动调整此缓冲区大小。禁用此选项应谨慎,在调优特定 GC 行为时可能会使用到。-XX:+ParallelRefProcEnabled
含义:启用并行处理引用类型(如 SoftReference、WeakReference、PhantomReference)的清理工作。这可以提高垃圾回收器在清理引用类型对象时的效率。
推荐用途:在有大量引用对象的应用中启用此参数有助于减少 GC 暂停时间。-XX:+ExplicitGCInvokesConcurrent
含义:当显式调用 System.gc() 时,使用并发垃圾收集而不是触发 Full GC。这可以避免 System.gc() 导致的长时间停顿。
推荐用途:如果应用中有显式的 System.gc() 调用,建议启用此选项,以减少性能开销。-XX:MaxGCPauseMillis=100
含义:设置 G1 垃圾收集器的最大暂停时间目标为 100 毫秒。G1 会尝试将 GC 暂停时间控制在此目标范围内,但这不是一个绝对的保证。
推荐用途:对于需要低延迟的应用,可以将暂停时间目标设置为较小值,但需要权衡回收效率和应用程序性能。-XX:+UseStringDeduplication
含义:启用字符串去重功能,G1 垃圾收集器会尝试查找并去重堆内存中重复的字符串,以减少内存占用。
推荐用途:如果应用中有大量重复的字符串对象,启用此选项可以显著降低内存消耗。-XX:+UnlockExperimentalVMOptions
含义:解锁 JVM 的实验性参数。这使得可以使用一些实验性功能或调优参数,这些功能通常还未成为默认选项。
推荐用途:仅在需要启用实验性功能或参数时使用,通常这些功能还处于试验阶段或不稳定。-XX:G1NewSizePercent=10
含义:设置年轻代(Young Generation)大小占整个堆大小的最小百分比,默认值通常为 5%。这里设置为 10%,即年轻代至少占整个堆的 10%。
推荐用途:可以通过调整年轻代大小来优化 GC 的频率和效率。增大年轻代适用于创建大量短命对象的应用。-XX:InitiatingHeapOccupancyPercent=60
含义:设置在 G1 垃圾收集器中,堆内存使用量达到 60% 时,开始标记周期以准备进行混合 GC。这是触发混合垃圾收集的阈值。
推荐用途:适用于需要较早进行老年代回收的场景,以避免老年代满时的长时间停顿。常见设置范围在 40%-50% 之间。
JDK17为了加快启动速度,支持了模块化编程,默认某些模块不开启需要哪个开启哪个,但是可能我们某些框架无法正常运行,比如反射包等一些包,因此需要手动开启模块:
复制粘贴版:
-Xms4G -Xmx4G -XX:MaxDirectMemorySize=2G -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M -XX:+UseG1GC -XX:+AlwaysPreTouch -XX:-ResizePLAB -XX:+ParallelRefProcEnabled -XX:+ExplicitGCInvokesConcurrent -XX:MaxGCPauseMillis=100 -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=10 -XX:InitiatingHeapOccupancyPercent=60 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED -Duser.timezone=Asia/Shanghai