Java虚拟机(JVM)调优是调整默认参数以满足我们的应用程序需求的过程。这包括简单的调整,例如堆的大小,通过选择正确的垃圾收集器来使用优化版本的 getter。
了解 Java 虚拟机 (JVM)
什么是 JVM?
Java 虚拟机 (JVM) 是 Java 生态系统中的关键组件,它使 Java 应用程序能够独立于平台。它解释Java字节码并将其作为各种操作系统上的机器代码执行,使得*"一次编写,随处运行"成为可能。*
优化垃圾收集
垃圾收集
Java 应用程序创建许多对象来处理传入的请求。在满足这些请求之后,对象就变成"垃圾"并且必须被清理。垃圾收集
(GC) 对于释放内存至关重要,但会减慢响应时间并增加 CPU 使用率。因此,调整GC对于优化性能非常重要。
ZGC算法
ZGC 的主要特点是专注于最大限度地减少 GC 暂停时间。它旨在确保暂停时间(通常为几毫秒),即使堆大小很大也是如此。
在需要低延迟性能、具有大堆或高吞吐量、低延迟用例的多线程或内存密集型应用程序中选择 ZGC。它最大限度地减少了暂停时间,通过大内存大小进行扩展,并提高了可预测性。
JVM 参数
为了在多线程或内存密集型服务中实现高吞吐量和低延迟,您必须调整 JVM 参数。
-Xss256k
- Java 中的
-Xss
选项用于设置 Java 虚拟机 (JVM) 中每个线程的线程堆栈大小。-Xss256k
选项专门将线程堆栈大小设置为 256 KB。该值在调整 Java 应用程序时非常有用,特别是在多线程场景中。 - 优点: 在高度并发的应用程序中,例如处理许多并发请求的服务器(例如,Web 服务器、消息代理等),减少线程堆栈大小可以通过允许创建更多线程而不达到内存限制来帮助防止内存耗尽。
-Xms<Size>g
- Java 中的
-Xms
JVM 选项指定应用程序启动时 JVM 的初始堆大小。 - 优点:大型 Web 应用程序、数据处理系统或内存数据库可能会受益于初始大型堆分配,以满足其内存需求,而无需在启动期间不断调整堆大小。
-Xmx<MaxSize>g
- Java 中的
-Xmx
JVM 选项设置 JVM 的最大堆大小。最大大小可以是 RAM 的 90%。 - 优点:
- 避免内存不足错误
- 优化 GC 性能
- 优化内存密集型应用程序(内存数据库、缓存等)
- 避免频繁调整堆大小
- 提高多线程应用程序的性能
-XX:+使用ZGC
- Java 中的
-XX:+UseZGC
选项在 JVM 中启用 ZGC。 ZGC 是一种低延迟垃圾收集器,旨在最大限度地减少垃圾收集期间的暂停时间,即使对于运行非常大的堆(高达 TB 内存)的应用程序也是如此。 - 优点:
- 低延迟GC
- 大堆的可扩展性
- 并发和增量GC
- 适用于容器化和云原生环境
- 即使在 Full GC 期间,暂停时间也很短
- 更适合多核系统
-XX:+Z世代
-XX:+ZGenerational
选项在 Java 中用于启用 ZGC 的分代模式。默认情况下,ZGC 作为非分代垃圾收集器运行,这意味着它在执行垃圾收集时将整个堆视为单个统一区域。- 优点:
- 提高具有许多短期对象的应用程序的性能
- 通过单独收集年轻代来减少 GC 暂停时间
- 改进堆管理
- 降低完整 GC 的成本
使用-XX:+ZGenerational
可以在 ZGC 中进行分代垃圾收集,这可以通过将短期和长期对象隔离到堆的不同区域来提高具有短期和长期对象混合的应用程序的性能。这可以带来更好的内存管理、减少暂停时间并提高可扩展性,特别是对于处理大量数据的大型应用程序。
-XX:SoftMaxHeapSize=<Size>g
-XX:SoftMaxHeapSize
JVM 选项用于设置 Java 应用程序最大堆大小的软限制。当您使用-XX:SoftMaxHeapSize=4g
时,您是在告诉 JVM 在正常情况下目标堆大小不超过 4 GB,但如有必要,允许 JVM 超过此限制。- 优点:
- 灵活的内存管理
- 处理内存激增而不崩溃
- 对于容器化或云环境有效
- 性能调优和资源优化
- 防止过度使用内存
-XX:+使用字符串重复数据删除
- Java 中的
-XX:+UseStringDeduplication
选项启用字符串重复数据删除作为垃圾收集过程的一部分。字符串重复数据删除是一种允许 JVM 识别并删除内存中重复字符串文字或相同字符串对象的技术,通过仅存储字符串值的一个副本,有效减少内存使用量,即使它在应用程序中出现多次。 - 优点:
- 减少重复字符串的内存使用
- 优化具有许多字符串的大型应用程序中的内存
- 适用于实习字符串
- 帮助处理大型文本数据
- 以最少的配置自动重复数据删除
使用-XX:+UseStringDeduplication
标志是优化 Java 应用程序中内存使用的好方法,尤其是那些处理大量重复字符串值的应用程序。通过启用重复数据删除,您可以允许 JVM 消除堆中字符串的冗余副本,这可以显着节省内存并提高内存密集型应用程序的性能。
-XX:+ClassUnloadingWithConcurrentMark
- 这
-XX:+ClassUnloadingWithConcurrentMark
Java 中的选项用于在垃圾收集的并发标记阶段启用类的并发卸载。当运行动态加载和卸载类的应用程序时,此选项特别有用,例如应用程序服务器(例如,Tomcat、Jetty)、框架或依赖于热交换或动态类加载的系统。 - 优点:
- 减少 GC 暂停时间
- 改进长寿命应用程序的内存管理
- 服务器和容器具有更好的可扩展性
- 热插拔和框架
-XX:+使用NUMA
-XX:+UseNUMA JVM
选项用于优化具有非统一内存访问 (NUMA) 架构的系统的 JVM。 NUMA 是一种用于多处理器系统的内存设计,其中每个处理器都有自己的本地内存,但它也可以访问其他处理器的内存,尽管延迟较高。-XX:+UseNUMA
选项使 JVM 能够优化基于 NUMA 的系统上的内存分配和垃圾收集,以提高性能。- 优点:
- 改善内存访问延迟和性能
- 更好的气相色谱效率
- 优化内存分配
- 多插槽系统上更好的可扩展性
什么是 NUMA?
在 NUMA 系统中,处理器连接到本地内存,并且每个处理器可以比连接到其他处理器的内存更快地访问自己的本地内存。与所有处理器对所有内存的访问时间相同的统一内存访问 (UMA) 系统相反,NUMA 系统由于本地内存与远程内存的延迟不同而具有不对称内存访问。
NUMA 架构通常用于具有多个处理器(或插槽)的大型服务器,通过确保尽可能在本地访问内存可以提高性能。
-XX:+UseNUMA 有什么作用?
当启用-XX:+UseNUMA
选项时,JVM 将配置为通过考虑系统的 NUMA 拓扑来优化内存访问。具体来说,JVM 将:
- 从与执行给定任务的处理器关联的本地 NUMA 节点分配内存(只要可能)。
- 使线程本地内存靠近运行线程的处理器,从而减少内存访问延迟。
- 通过优化 JVM 跨多个 NUMA 节点管理堆和其他内存资源的方式来提高垃圾收集性能。
-XX:ConcGCThreads=<size>
- Java 中的
-XX:ConcGCThreads
选项允许您控制 JVM 在垃圾收集的并发阶段使用的并发 GC 线程的数量。 - 优点:
- 控制GC中的并行度
- 最大限度地减少垃圾收集暂停时间
- 根据硬件资源优化性能
- 提高多线程应用程序的吞吐量
-XX:ConcGCThreads 有什么作用?
当 JVM 执行垃圾收集时,某些收集器(例如 G1 GC 或 ZGC)可以同时执行垃圾收集的各个阶段,这意味着它们与应用程序线程并行运行,以最大限度地减少暂停时间并提高吞吐量。 -XX:ConcGCThreads
选项允许您指定 JVM 在这些并发 GC 阶段应使用多少个线程。
-XX:+Z取消提交
-XX:+ZUncommit
JVM 选项用于控制 ZGC 中内存管理的行为,特别与 JVM 在为堆分配内存后如何从操作系统释放(或取消提交)内存有关。- 优点:
- 减少内存占用
- 低内存环境下的动态内存回收
- 避免内存碎片
- 优化 GC 开销
-XX:+AlwaysPreTouch
-XX:+AlwaysPreTouch
JVM 选项用于预先接触 JVM 将用于其堆的内存页面,这意味着一旦分配了堆,JVM 将立即接触每个内存页面(即访问它)。而不是在实际需要时懒洋洋地触摸页面。- 优点:
- 减少应用程序运行时的延迟
- 防止初始执行期间出现操作系统页面错误
- 在大型堆应用程序中预加载虚拟内存
- 提高多核系统中的内存分配效率
- 避免启动期间内存交换
-XX:MaxGCPauseMillis=<size>
- Java 中的
-XX:MaxGCPauseMillis
选项用于设置 GC 期间可接受的最大暂停时间的目标。当您指定-XX:MaxGCPauseMillis=100
时,您将指示 JVM 的垃圾收集器将最大 GC 暂停时间设定为 100 毫秒。 - 优点:
- 最大限度地减少应用程序延迟
- 控制和平衡吞吐量与暂停时间
- 针对交互式或高通量系统进行了优化
- G1 GC 中的垃圾收集调整
- 改进了 Web 和服务器应用程序的用户体验
- 与 ZGC 和其他低延迟垃圾收集器一起使用
-XX:+使用大页
-XX:+UseLargePages
JVM 选项用于使 JVM 能够将大内存页面(也称为巨页或超级页面)用于 Java 堆和内存的其他部分,例如元空间和 JIT(Just-In-时间)编译缓存。- 优点:
- 提高内存访问性能
- 减少操作系统开销
- 内存密集型应用程序的更好性能
- 减少内存碎片
- 减少内存分页活动
-XX:+UseLargePages 的作用是什么?
操作系统通常以页为单位管理内存,页是内存分配和管理的基本单位。在许多系统上,内存页面的大小通常默认为 4 KB,但某些系统支持更大的页面大小 --- 通常为 2 MB(在 x86-64 Linux 和 Windows 系统上),对于某些处理器和配置甚至为 1 GB。
-XX:+使用TransparentHugePages
-XX:+UseTransparentHugePages
JVM 选项允许在 Java 虚拟机 (JVM) 中使用透明大页 (THP) 进行内存管理。透明大页是一项 Linux 内核功能,旨在自动管理大内存页,从而提高内存密集型应用程序的性能。
调优参数:
bash
java -Xss256k -Xms1g -Xmx4g -XX:+UseZGC -XX:+UseStringDeduplication -XX:+ZGenerational -XX:SoftMaxHeapSize=4g -XX:+ClassUnloadingWithConcurrentMark -XX:+UseNUMA -XX:ConcGCThreads=4 -XX:+ZUncommit -XX:+AlwaysPreTouch -XX:MaxGCPauseMillis=100 -XX:+UseLargePages -XX:+UseTransparentHugePages org.springframework.boot.loader.launch.JarLauncher