高性能JVM的参数

-Xmx 和 -Xms

-Xmx 可能是最重要的 JVM 参数。
-Xmx 定义分配给应用程序的最大堆大小。
-Xms 定义分配给应用程序的最小堆大小。
示例:

-Xmx1g -Xms1g

推荐:-Xmx 和 -Xms 设置一样大小,避免频繁的向 OS 申请内存空间,提升JVM性能

-XX:MaxMetaspaceSize

元空间是 JVM 的元数据定义(例如类定义、方法定义)将被存储的区域。默认情况下,可用于存储此元数据信息的内存量是无限的(即受容器或机器的 RAM 大小限制)。需要使用 -XX:MaxMetaspaceSize 参数来指定可用于存储元数据信息的内存量的上限。

示例:

-XX:MaxMetaspaceSize=384m

-Xss

每个应用程序将有数十、数百、数千个线程。每个线程都有自己的堆栈。在每个线程的堆栈中存储以下信息:

  • 当前执行的方法或者函数(程序计数器)
  • 原始数据类型
  • 对象指针
  • 线程私有变量
  • 返回值

它们中的每一个都消耗内存。如果它们的消耗超过一定的限制,则抛出 StackOverflowError。
如果将此 -Xss 值设置为一个巨大的数字,那么内存将被阻塞和浪费。假设将 -Xss 值分配为 2mb,而它只需要 256kb,那么最终将浪费大量内存,而不仅仅是 1792kb(即 2mb – 256kb)

假设您的应用程序有 500 个线程,然后 -Xss 值为 2mb,线程将消耗 1000mb 的内存(即 500 个线程 x 2mb/线程)。另一方面,如果仅将 -Xss 分配为 256kb,那么您的线程将仅消耗 125mb 的内存(即 500 个线程 x 256kb/线程)。将为每个 JVM 节省 875mb(即 1000mb – 125mb)的内存。
注意:线程是在堆外创建的,使用的是操作的内存,而不是 -Xmx配置的内存 每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。前面我们曾经提到,Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。
建议是从较低的值(比如 256kb)开始。使用此设置运行彻底的回归、性能和 AB 测试。仅当您遇到 StackOverflowError 时才增加该值,否则请考虑坚持较低的值。
测试用例如图:
在这里插入图片描述
测试代码如下:

/**
 * @author chunyang.leng
 * @date 2022-07-12 9:52 AM
 */
public class XssTest {

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(()->{
                try {
                    String name = Thread.currentThread().getName();
                    System.out.println(name + " sleep");
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            thread.start();
        }
        System.out.println("main sleep");
        Thread.sleep(Integer.MAX_VALUE);
    }
}

-Dsun.net.client.defaultConnectTimeout 和 -Dsun.net.client.defaultReadTimeout

现代应用程序使用多种协议(即 SOAP、REST、HTTP、HTTPS、JDBC、RMI…)来连接远程应用程序。有时远程应用程序可能需要很长时间才能响应。有时它可能根本没有反应。

如果您没有适当的超时设置,并且如果远程应用程序响应不够快,那么您的应用程序线程/资源将被卡住。远程应用程序无响应会影响应用程序的可用性。它可以使您的应用程序陷入停顿。为了保护您的应用程序的高可用性,应配置适当的超时设置。

您可以在 JVM 级别传递这两个强大的超时网络属性,这些属性可以全局适用于所有使用 java.net.URLConnection 的协议处理程序:

sun.net.client.defaultConnectTimeout 指定与主机建立连接的超时时间(以毫秒为单位)。例如,对于 HTTP 连接,它是与 HTTP 服务器建立连接时的超时。
sun.net.client.defaultReadTimeout 指定与资源建立连接时从输入流中读取的超时时间(以毫秒为单位)。这两个值的默认值为 -1 ,就是说,没有设置超时时间
示例:

# 设置默认值为 2 秒
-Dsun.net.client.defaultConnectTimeout=2000
-Dsun.net.client.defaultReadTimeout=2000

-Duser.timeZone

如果您的应用程序跨多个数据中心运行,例如美国、日本、中国,那么每个数据中心中的 JVM 最终将具有不同的时区。因此,每个数据中心的 JVM 会表现出不同的行为。这将导致不一致的结果,为避免这些混乱,强烈建议使用 -Duser.timezone 系统属性在 JVM 上设置时区。例如,应用程序设置 Asia/Shanghai时区

-Duser.timezone=Asia/Shanghai

GC回收器

目前 JVM 一共有以下几种GC回收器

  • Serial GC (串行GC)
  • Parallel GC (并行GC)
  • Concurrent Mark & Sweep GC (并发标记和扫描 GC)
  • G1 GC
  • Shenandoah GC
  • Z GC
  • Epsilon GC

如果你没有明确指定 GC 回收器,那么 JVM 会选择默认回收器。在 Java 8 之前,Parallel GC 是默认的 GC 回收器。从 Java 9 开始,G1 GC 是默认的 GC 回收器。
GC 回收器的选择在确定应用程序的性能方面起着至关重要的作用。如果使用 JVM 11+ 运行,那么可以考虑使用 Z GC 算法(即 -XX:+UseZGC),open jdk Z GC 调优链接
各种GC启动参数

GC 算法JVM 参数
Serial GC-XX:+UseSerialGC
Parallel GC-XX:+UseParallelGC
Concurrent Market & Sweep (CMS) GC-XX:+UseConcMarkSweepGC
G1 GC-XX:+UseG1GC
Shenandoah GC-XX:+UseShenandoahGC
Z GC-XX:+UseZGC
Epsilon GC-XX:+UseEpsilonGC

GC日志

垃圾收集日志包含有关垃圾收集事件、内存回收、暂停时间持续时间的信息。
从 JDK 1 到 JDK 8:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:{file-path}

从 JDK 9 及更高版本:

-Xlog:gc*:file={file-path}

示例:

# jdk8
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/workspace/myAppgc.log
# jdk9
-Xlog:gc*:file=/opt/workspace/myAppgc.log

-XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath

OutOfMemoryError是一个严重的问题,会影响应用程序的可用性/性能 SLA。要诊断 OutOfMemoryError 或任何与内存相关的问题,必须在应用程序开始遇到OutOfMemoryError之前的那一刻或几分钟捕获堆转储。由于我们不知道什么时候会抛出 OutOfMemoryError,所以很难在抛出的时候手动捕获堆转储。但是,可以通过传递以下 JVM 参数来自动捕获堆转储:

 -XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath={HEAP-DUMP-FILE-PATH}

在“-XX:HeapDumpPath”中,需要指定应该存储堆转储的文件路径。当传递这两个 JVM 参数时,当抛出 OutOfMemoryError 时,堆转储将被自动捕获并写入定义的文件路径。

示例:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/root/my-heap-dump.hprof
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JVM参数调优是为了提高Java应用程序的性能和稳定性。下面是一些常见的JVM参数调优的思路和建议: 1. 堆内存设置: - -Xms: 初始堆大小,建议与-Xmx相同,避免堆大小的动态调整。 - -Xmx: 最大堆大小,根据应用程序的需求进行设置,避免频繁的垃圾回收。 2. 垃圾回收器选择: - -XX:+UseParallelGC: 使用并行垃圾回收器,适合多核CPU和高吞吐量应用。 - -XX:+UseConcMarkSweepGC: 使用CMS垃圾回收器,适合响应时间优先的应用。 - -XX:+UseG1GC: 使用G1垃圾回收器,适合大内存应用和低延迟要求。 3. 垃圾回收参数调优: - -XX:NewRatio: 设置新生代和老年代的比例,默认为2,可以根据应用程序的对象生命周期进行调整。 - -XX:SurvivorRatio: 设置Eden区和Survivor区的比例,默认为8,可以根据对象的存活率进行调整。 - -XX:MaxTenuringThreshold: 设置对象进入老年代的年龄阈值,默认为15,可以根据对象的存活率和内存情况进行调整。 4. 线程相关参数: - -Xss: 设置线程栈的大小,默认为1M,可以根据应用程序的线程数量进行调整。 - -XX:ParallelGCThreads: 并行垃圾回收的线程数量,默认为CPU核心数的1/8,可以根据CPU和内存情况进行调整。 5. 其他常用参数: - -XX:+UseCompressedOops: 使用压缩指针,可以减少对象引用的内存消耗。 - -XX:+DisableExplicitGC: 禁用显示调用System.gc()方法,避免不必要的垃圾回收。 以上是一些常见的JVM参数调优策略,具体的调优效果和最佳参数设置还需要根据应用程序的实际情况进行测试和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北漂的菜小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值