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