jdk17编译spring

编译 spring-framework

需要注意的地方:

setting.gradle

1
2
添加module
#比如test-me

运行参数为:

1
-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 -XX:MaxRAMPercentage=45 -XX:InitialRAMPercentage=45 -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -XX:+AlwaysPreTouch -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MaxMetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+DisableExplicitGC -XX:+UseZGC -XX:-UseBiasedLocking -XX:GuaranteedSafepointInterval=0 -XX:+UseCountedLoopSafepoints -XX:+SafepointTimeout -XX:SafepointTimeoutDelay=1000 -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 参数

目前正常微服务综合内存占用+延迟+吞吐量,还是 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 -XX:MaxRAMPercentage=45 -XX:InitialRAMPercentage=45 -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -XX:+AlwaysPreTouch -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MaxMetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+DisableExplicitGC -XX:MaxGCPauseMillis=50 -XX:-UseBiasedLocking -XX:GuaranteedSafepointInterval=0 -XX:+UseCountedLoopSafepoints -XX:+SafepointTimeout -XX:SafepointTimeoutDelay=1000 -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 -XX:MaxRAMPercentage=45 -XX:InitialRAMPercentage=45 -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -XX:+AlwaysPreTouch -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MaxMetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+DisableExplicitGC -XX:+UseZGC -XX:-UseBiasedLocking -XX:GuaranteedSafepointInterval=0 -XX:+UseCountedLoopSafepoints -XX:+SafepointTimeout -XX:SafepointTimeoutDelay=1000 -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 复制代码 其中,需要做成环境变量外部可以配置的是:

-XX:MaxRAMPercentage=45 -XX:InitialRAMPercentage=45 -Xss512k -XX:MaxDirectMemorySize=1024m -XX:MaxMetaspaceSize=384m -XX:ReservedCodeCacheSize=256m 里面的参数 -XX:StartFlightRecording=disk=true,maxsize=4096m,maxage=3d 其中的 4096m 以及 3d -XX:MaxGCPauseMillis=50:这个只有使用 G1GC 的需要

JVM 日志相关: JVM 日志配置请参考:zhuanlan.zhihu.com/p/111886882

需要异步输出日志,防止卡死 JVM:-Xlog:async 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,我们应用已经对于大量报错的时候输出大量堆栈导致性能压力的优化,参考:zhuanlan.zhihu.com/p/428375711

系统属性(环境变量)启动参数:

-Dfile.encoding=UTF-8:指定编码为 UTF-8,其实 Java 18 之后默认编码就是 UTF-8 了,这样避免不同操作系统编译带来的差异(Windows 默认是 GB2312,Linux 默认是 UTF-8),参考:openjdk.java.net/jeps/400 -Djava.security.egd=file:/dev/./urandom:更换 random 为 urandom 避免高并发加密证书通信的时候的生成随机数带来的阻塞(例如高并发 https 请求,高并发 mysql 连接通信),参考:zhuanlan.zhihu.com/p/259874076 -Dnetworkaddress.cache.ttl=10:将 DNS 缓存降低为 10s 过期,咱们 k8s 内部有很多通过域名解析的资源(通过 k8s 的 coreDNS),解析的 ip 可能会过期,漂移成新的 ip,默认的 30s 有点久,改成 10s,但是这会增加 coreDNS 的压力。

内存控制相关: 以下需要做成可以在外部配置的环境变量:

堆内存控制:-XX:MaxRAMPercentage=45 -XX:InitialRAMPercentage=45 -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 (使用系统可用内存百分比配置堆,堆内存一般占用系统内存的少一半,其他的给堆外内存使用,比如 GC,元空间,Tracing 等等,同时设置 MinHeapFreeRatio 为最小值,MaxHeapFreeRatio 为最大值是为了避免 GC 的时候动态伸缩堆大小) 线程栈大小控制:-Xss512k 直接内存(各种 Direct Buffer)大小控制:-XX:MaxDirectMemorySize=1024m 元空间控制:-XX:MaxMetaspaceSize=384m JIT 即时编译后(C1 C2 编译器优化)的代码占用内存:-XX:ReservedCodeCacheSize=256m 内存初始化(针对堆内存,申请并 commit 了 InitialRAMPercentage 大小后立刻填充 0 让系统真的把内存分配给 JVM):-XX:+AlwaysPreTouch

除了以上内存,JVM 还有其他内存占用,无法通过显示的配置限制,参考:www.zhihu.com/question/58… 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

安全点控制 关于安全点,可以查看这篇文章:zhuanlan.zhihu.com/p/161710652

-XX:-UseBiasedLocking:禁用偏向锁,偏向锁其实未来会被完全移除(参考:),目前咱们都是高并发的环境,偏向锁基本没啥用并且还有负面影响 -XX:GuaranteedSafepointInterval=0:禁用定时安全点任务,没必要,咱们不是那种热点代码经常改变,资源珍贵的场景,并且如果是 ZGC 本身就会定时进入安全点进行 GC 检查,更没必要了 -XX:+UseCountedLoopSafepoints:防止大有界循环带来的迟迟不进入安全点导致 GC STW 时间过长 -XX:+SafepointTimeout -XX:SafepointTimeoutDelay=1000:防止其他情况下导致进入安全点时间过长导致 STW 时间过长,这里配置的是 1s。但是没有指定 AbortVMOnSafepointTimeout 为 true,所以对你的 jmap 以及 jstack 命令没有影响

JFR 配置 JFR 使用请参考: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: openjdk.java.net/jeps/396),J… 17 直接移除了这个选项 (JEP: 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

ignore 的 file 讲解

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
#======================================================================================================================
#=========================================          gitignore的基础用法         =========================================
#======================================================================================================================
#  一.基础语法
#    .gitignore配置文件的一些通用技巧 [参考:https://git-scm.com/docs/gitignore]
#     1.空白行不匹配任何文件,所以可以作为可读性的分隔符,同时两端的空格将会被忽略.
#     2.使用[#]开头,将会注释掉整行,使其不进行匹配操作,如果需要匹配#开头,可以使用转义字符[\].
#     3.1匹配模式以[/]结尾,表示想要匹配一个目录及其子文件.(比如[foo/]会匹配foo目录及其下面的路径.)
#     3.2匹配模式不包含[/],将会全局匹配该文件.
#     4.通配符
#       [*]:  匹配除[/]以外的任何内容,也就意味着[*]不能跨目录.
#       [?]:  匹配除[/]和[[]以及[]]以外的任何一个字符.
#       [**]: 匹配所有的内容,或者说匹配任意目录下的内容.
#         示例:
#           1.[**/foo/bar]  将会匹配所有直接在foo目录下的bar,无论foo处在何处.
#           2.[foo/**]则表示匹配foo目录下的所有文件和目录.
#           3.[a/**/b]则可以匹配a/b, a/c/b, a/c/d/b,即此处的[**]可以表示0个或多个.
#           !!! 需要注意的是,除上面示例的用法外,剩余的[**]都是无效的..
#     5.可以通过前缀[!]来表示不忽略某些文件,比如可以通过[!a]来确保文件a不会被忽略,即时前面已经声明了忽略其父目录,该模式优先级高于普通忽略模式.
#  二.常用命令
#    1.git -rm  [https://git-scm.com/docs/git-rm]
#      删除文件索引,或者同时删除文件索引和物理文件.可以使用通配符.
#    2.git-check-ignore [https://git-scm.com/docs/git-check-ignore]
#      调试.gitignore文件
#  三.注意事项
#    1.如果文件已经被git管理,那么后续添加的忽略模式将不会生效,具体解决方法,参考<<二.常用命令>>.

#=======================================================================================================================
#==============================               java忽略文件                           =====================================
#=====================         https://github.com/github/gitignore/blob/master/Java.gitignore         ==================
#=======================================================================================================================
# 编译后的class文件,忽略所有以[.class]结尾的文件
*.class

# 日志文件,忽略所有以[.log]结尾的文件.
*.log

# BlueJ 文件,忽略所有以[.ctxt]结尾的文件.
*.ctxt

# Mobile Tools for Java (J2ME),忽略[.mtj.tmp/]目录及其子文件.
.mtj.tmp/

# 打包文件,忽略所有以[.jar]或[.war]或[.nar]或[.ear]或[.zip]或[.tar.gz]或[rar]结尾的文件.
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# 虚拟机崩溃日志,忽略所有以[hs_err_pid]开头的文件.[see http://www.java.com/en/download/help/error_hotspot.xml]
hs_err_pid*
#=======================================================================================================================
#==============================               maven忽略文件                           ===================================
#=====================         https://github.com/github/gitignore/blob/master/Maven.gitignore        ==================
#=======================================================================================================================
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
#=======================================================================================================================
#==============================               IDE环境忽略文件                           ==================================
#=====================         https://github.com/github/gitignore/blob/master/Maven.gitignore        ==================
#=======================================================================================================================
#----------------IDEA-------------
.idea/*
.idea/compiler.xml
.idea/encodings.xml
.idea/modules.xml
*.iml
#=======================================================================================================================
#==============================               other环境忽略文件                           ================================
#=====================         https://github.com/github/gitignore/blob/master/Maven.gitignore        ==================
#=======================================================================================================================
*.sw?
.#*
*#
*~
.classpath
.project
.settings/
bin
build
target
dependency-reduced-pom.xml
*.sublime-*
/scratch
.gradle
Guardfile
README.html
*.iml
.idea

程序运行结果为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
> Task :test-me:ApplicationContextTest.main()
[0.002s][warning][logging] Output options for existing outputs are ignored.
[0.002s][warning][logging] Output options for existing outputs are ignored.
[0.002s][warning][logging] Output options for existing outputs are ignored.
OpenJDK 64-Bit Server VM warning: Option UseBiasedLocking was deprecated in version 15.0 and will likely be removed in a future release.
OpenJDK 64-Bit Server VM warning: Option UseBiasedLocking was deprecated in version 15.0 and will likely be removed in a future release.
When counted loop safepoints are enabled, LoopStripMiningIter must be at least 1 (a safepoint every 1 iteration): setting it to 1
[4.013s][info   ][jfr,startup] Started recording 1.
[4.013s][info   ][jfr,startup]
[4.013s][info   ][jfr,startup] Use jcmd 8595 JFR.dump name=1 filename=FILEPATH to copy recording data to file.
[4.033s][info   ][jfr,startup] Started recording 2.
[4.033s][info   ][jfr,startup]
[4.033s][info   ][jfr,startup] Use jcmd 8595 JFR.dump name=2 filename=FILEPATH to copy recording data to file.
你好: 123io.mvvm.Mybean@5340477f
hello world
Licensed under CC BY-NC-SA 4.0
最后更新于 Jan 06, 2025 05:52 UTC
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计
Caret Up