我所使用的生产 Java 17 启动参数
JVM 参数升级提示工具:jacoline.dev/inspect
JVM 参数词典:chriswhocodes.com
Revolut(英国支付巨头)升级 Java 17 实战:https://www.bilibili.com/video/bv1SA4y1d7sZ
目前正常微服务综合内存占用+延迟+吞吐量,还是 G1 更优秀。但是如果你的微服务本身压力没到机器极限,要求延迟低,那么 ZGC 最好。如果你是实现数据库那样的需求(大量缓存对象,即长时间生存对象,老年代很大,并且还会可能分配大于区域的对象),那么必须使用 ZGC。
使用 G1GC 启动参数:
-XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:-OmitStackTraceInFastThrow -Xlog:gc*=debug:file=${LOG_PATH}/gc%t.log:utctime,level,tags:filecount=50,filesize=100M -Xlog:jit+compilation=info:file=${LOG_PATH}/jit_compile%t.log:utctime,level,tags:filecount=10,filesize=10M -Xlog:safepoint=debug:file=${LOG_PATH}/safepoint%t.log:utctime,level,tags:filecount=10,filesize=10M -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom -Dnetworkaddress.cache.ttl=10 -Xms2048m -Xmx2048m -Xmn1280m -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+DisableExplicitGC -XX:MaxGCPauseMillis=50 -XX:-UseBiasedLocking -XX:GuaranteedSafepointInterval=0 -XX:+UseCountedLoopSafepoints -XX:StartFlightRecording=disk=true,maxsize=4096m,maxage=3d -XX:FlightRecorderOptions=maxchunksize=128m --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
使用 ZGC 启动参数:
-XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:-OmitStackTraceInFastThrow -Xlog:gc*=debug:file=${LOG_PATH}/gc%t.log:utctime,level,tags:filecount=50,filesize=100M -Xlog:jit+compilation=info:file=${LOG_PATH}/jit_compile%t.log:utctime,level,tags:filecount=10,filesize=10M -Xlog:safepoint=debug:file=${LOG_PATH}/safepoint%t.log:utctime,level,tags:filecount=10,filesize=10M -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom -Dnetworkaddress.cache.ttl=10 -Xms2048m -Xmx2048m -Xmn1280m -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+DisableExplicitGC -XX:+UseZGC -XX:-UseBiasedLocking -XX:GuaranteedSafepointInterval=0 -XX:+UseCountedLoopSafepoints -XX:StartFlightRecording=disk=true,maxsize=4096m,maxage=3d -XX:FlightRecorderOptions=maxchunksize=128m --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
其中,需要做成环境变量外部可以配置的是:
-Xms2048m -Xmx2048m -Xmn1280m -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MetaspaceSize=384m -XX:ReservedCodeCacheSize=256m里面的参数-XX:StartFlightRecording=disk=true,maxsize=4096m,maxage=3d其中的 4096m 以及 3d-XX:MaxGCPauseMillis=50:这个只有使用 G1GC 的需要
JVM 日志相关:
JVM 日志配置请参考:https://zhuanlan.zhihu.com/p/111886882
- GC日志:
-Xlog:gc*=debug:file=${LOG_PATH}/gc%t.log:utctime,level,tags:filecount=50,filesize=100M - JIT 编译日志:
-Xlog:jit+compilation=info:file=${LOG_PATH}/jit_compile%t.log:utctime,level,tags:filecount=10,filesize=10M - Safepoint 日志:
-Xlog:safepoint=debug:file=${LOG_PATH}/safepoint%t.log:utctime,level,tags:filecount=10,filesize=10M - 关闭堆栈省略:这个只会省略 JDK 内部的异常,比如 NullPointerException 这种的:
-XX:-OmitStackTraceInFastThrow,我们应用已经对于大量报错的时候输出大量堆栈导致性能压力的优化,参考:https://zhuanlan.zhihu.com/p/428375711
系统属性(环境变量)启动参数:
-Dfile.encoding=UTF-8:指定编码为 UTF-8,其实 Java 18 之后默认编码就是 UTF-8 了,这样避免不同操作系统编译带来的差异(Windows 默认是 GB2312,Linux 默认是 UTF-8),参考:https://openjdk.java.net/jeps/400-Djava.security.egd=file:/dev/./urandom:更换 random 为 urandom 避免高并发加密证书通信的时候的生成随机数带来的阻塞(例如高并发 https 请求,高并发 mysql 连接通信),参考:https://zhuanlan.zhihu.com/p/259874076-Dnetworkaddress.cache.ttl=10:将 DNS 缓存降低为 10s 过期,咱们 k8s 内部有很多通过域名解析的资源(通过 k8s 的 coreDNS),解析的 ip 可能会过期,漂移成新的 ip,默认的 30s 有点久,改成 10s,但是这会增加 coreDNS 的压力。
内存控制相关:
以下需要做成可以在外部配置的环境变量:
- 堆内存控制:
-Xms2048m -Xmx2048m -Xmn1280m - 线程栈大小控制:
-Xss512k - 直接内存(各种 Direct Buffer)大小控制:
-XX:MaxDirectMemorySize=1024m - 元空间控制:
-XX:MetaspaceSize=384m - JIT 即时编译后(C1 C2 编译器优化)的代码占用内存:
-XX:ReservedCodeCacheSize=256m
除了以上内存,JVM 还有其他内存占用,无法通过显示的配置限制,参考:https://www.zhihu.com/question/58943470/answer/2440458704
GC 控制相关:
通用参数:
-XX:+DisableExplicitGC:关闭显示 GC(System.gc()触发的 FullGC),防止 netty 这种误检测内存泄漏显示调用
G1GC 参数:
Java 9 之后默认 GC 就是 G1GC,所以不用显示指定使用 G1GC
在 Java 14 之后 G1GC 有巨大突破,目前 Java 17 中已经不需要调非常复杂的参数了,可以只调整目标最大 STW(Stop-the-world) 时间来均衡 CPU 占用,内存占用与延迟。
-XX:MaxGCPauseMillis=50:目标最大 STW(Stop-the-world) 时间,这个越小,GC 占用 CPU 资源,占用内存资源就越多,微服务吞吐量就越小,但是延迟低。这个需要做成可配置的
ZGC 参数:
ZGC 不用调优,是自适应的
-XX:+UseZGC:使用 ZGC
安全点控制
关于安全点,可以查看这篇文章:https://zhuanlan.zhihu.com/p/161710652
-XX:-UseBiasedLocking:禁用偏向锁,偏向锁其实未来会被完全移除(参考:),目前咱们都是高并发的环境,偏向锁基本没啥用并且还有负面影响-XX:GuaranteedSafepointInterval=0:禁用定时安全点任务,没必要,咱们不是那种热点代码经常改变,资源珍贵的场景,并且如果是 ZGC 本身就会定时进入安全点进行 GC 检查,更没必要了-XX:+UseCountedLoopSafepoints:防止大有界循环带来的迟迟不进入安全点导致 GC STW 时间过长
JFR 配置
JFR 使用请参考:https://zhuanlan.zhihu.com/p/161710652
-XX:StartFlightRecording=disk=true,maxsize=4096m,maxage=3d -XX:FlightRecorderOptions=maxchunksize=128m
模块化限制
--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
Java 16 将 --illegal-access 的默认值从 permit 改成了 deny (JEP: https://openjdk.java.net/jeps/396),Java 17 直接移除了这个选项 (JEP: https://openjdk.java.net/jeps/403),所以现在要打破模块化封装,必须通过这个命令具体打破某些模块向某些模块的暴露。这里包含了一些常用的可能会被反射访问的 java.base 下的 package,向所有未命名模块暴露(我们自己的项目一般不会指定模块名,如果你指定了就换成具体你的模块名)
这个也能从下面的报错中看出:
Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @7586beff
现在启动参数配置有点复杂,没法指定某个模块下的所有包都向某个模块暴露,并且未来也没有这个打算,参考:https://jigsaw-dev.openjdk.java.narkive.com/Zd1RvaeX/add-opens-for-entire-module
微信搜索“干货满满张哈希”关注公众号,加作者微信,每日一刷,轻松提升技术,斩获各种offer:
我会经常发一些很好的各种框架的官方社区的新闻视频资料并加上个人翻译字幕到如下地址(也包括上面的公众号),欢迎关注:
我所使用的生产 Java 17 启动参数的更多相关文章
- java程序启动参数-D含义详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt407 java程序启动参数 -D是用来做什么的呢?去查询了一下官方解释: S ...
- java 虚拟机启动参数 (转)
在Java.J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能. JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置.但是在生产环境中,为了提 ...
- java虚拟机启动参数分类详解
官方文档见: http://docs.sun.com/source/819-0084/pt_tuningjava.html java启动参数共分为三类:其一是标准参数(-),所有的JVM实现都必须实现 ...
- java虚拟机启动参数整理
java启动参数 共分为三类其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容:其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不 ...
- Java JVM启动参数
转载于:https://www.cnblogs.com/w-wfy/p/6415856.html java启动参数共分为三类其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容 ...
- Java JVM 启动参数
JVM 启动参数 java -Xmx4096m // 设置JVM最大可用内存为4096m. -Xms4096m // 设置JVM促使内存为4096m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成 ...
- java程序启动参数
例如 启动进程如下 /home/work/noah/ccs/jc-controller/jdk1.7.0_55/bin/java -Xmx4096m -Xms4096m -Xmn1024m -XX:+ ...
- 内存不足导致的java.lang.OutOfMemoryError: java heap space引出java工程启动参数设置
今天做分类实验,生成了190m的kernel文件,在读到svm中的时候跳出了java.lang.OutOfMemoryError: java heap space异常.随便搜了一下,发现与eclips ...
- java 8 启动脚本优化
1 #!/bin/bash 2 3 JAVA_HOME=/usr/java/default 4 5 #java虚拟机启动参数 6 JAVA_OPTS="-server -Xms1366m - ...
随机推荐
- 使用Socket实现HttpServer(三)
使用Socket实现HttpServer(三) 这一章继续对我们的服务器进行优化,引入 NIO package com.fengsir.network.step4; import java.io.IO ...
- Mybatis多表查询出现null字段
写在前面 今天使用mybatis实现多表查询,记录一下其中遇到的坑 mybatis多表查询简介 mybatis多表查询主要有两个方式,通俗易懂的来说就是一个是查询少量属性(association),一 ...
- 基于Apache组件,分析对象池原理
池塘里养:Object: 一.设计与原理 1.基础案例 首先看一个基于common-pool2对象池组件的应用案例,主要有工厂类.对象池.对象三个核心角色,以及池化对象的使用流程: import or ...
- 关于javaweb学习终点的一些感悟
学习完javaweb后,自己做了一套管理项目,使用了mybatis,themeleaf和servlet.大致明白了servlet的真实应用场景. 说白了servlet就是用来指定浏览器url后面输入了 ...
- Ubu18安装RabbitMQ
RabbitMQ安装 https://www.jianshu.com/p/5c8c4495827f 安装 RabbitMQ基于erlang语言,需要先安装 sudo apt-get install e ...
- Java学习day42
继续刷力扣题
- 『现学现忘』Git基础 — 4、Git下载与安装
目录 1.Git下载 2.Git在Windows下的详细安装 3.验证Git是否安装成功 1.Git下载 进入官方地址下载Git客户端:https://git-scm.com/download/win ...
- partOneJava学习卷土重来-----第一次测试题目介绍
石家庄铁道大学2021年秋季 2020 级课堂测试试卷(一)(15分) 课程名称: JAVA语言程序设计 任课教师: 王建民 考试时间: 150 分钟 一.考试要求: 1.按照测试 ...
- Math内置对象 常用的方法
属性: Math.Pi 方法: Math.max() 最大值 Math.min() 最小值 Math.ceil() 向上取整 Math.floor() 向下取整 Math.random() ...
- python基础练习题(题目 输出一个随机数。)
day35 --------------------------------------------------------------- 实例050:随机数 题目 输出一个随机数. 分析:使用ran ...
