程序配置JVM参数!❤️大家都这么用!

907 阅读4分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

本文介绍了将SpringBoot在Linux下作为服务启动的方式,同时介绍了自定义JVM启动参数的方法。

方法1. 启动时加上jvm参数

  • 执行启动设置JVM参数的操作。

java -jar-Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -XX:+UseConcMarkSweepGCxxx-1.0.0.jar

  • 程序在后台运行

nohup java -jar -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -XX:+UseConcMarkSweepGCxxx-1.0.0.jar &

方法2. 同一目录级别下增加xxx.conf文件,文件名要和jar包相同

  1. 要确保系统的service服务访问到java环境
[root@iZbp1bunl8t8qf63wqsy0iZ system]# whereis java
java: /mydata/jdk/jdk1.8.0_291/bin/java /mydata/jdk/jdk1.8.0_291/jre/bin/java
[root@iZbp1bunl8t8qf63wqsy0iZ system]# ln -s  /mydata/jdk/jdk1.8.0_291/bin/java /sbin/java
  1. 要注册成服务

vi /etc/systemd/system/myapp.service

[Unit]
Description=myapp
After=syslog.target

[Service]
User=root
ExecStart=/app/test/myapp.jar
#SuccessExitStatus=143
Type=simple

[Install]
WantedBy=multi-user.target

  1. 编写config文件

在启动SpringBoot服务之前,会先去jar包所在的同级目录下查找,有没有此jar的同名配置文件。

因此在部署项目的xxx.jar包同一目录级别下增加xxx.config文件,文件名要和jar包相同,并在文件里面自定义JVM参数JAVA_OPTS

xxx.conf格式如下:

JAVA_OPTS=-XX:MaxMetaspaceSize=128m

image.png

添加配置文件之后,重启服务

systemctl daemon-reload

sudo systemctl start myapp

再次查看服务进程:ps -ef | grep xxx,参数已生效

image.png

关于程序注册服务,大家可以参考我之前写的一篇文章:linux小技巧:注册为服务,设置开机启动 - 掘金 (juejin.cn)

参考:Deploying Spring Boot Applications

打印出所有参数选项的开始的默认值

-XX:+PrintFlagsInitial image.png

  • 第一列表示参数的数据类型
  • 第二列是名称
  • 第三列”=”表示第四列是参数的默认值,如果是”:=” 表明了参数被用户或者JVM赋值了
  • 第四列为值
  • 第五列是参数的类别 注:只是开始的默认值,JVM可能会改变一些值

打印运行程序时生效的参数

-XX:+PrintFlagsFinal

  • ":=" 表明了参数被用户或者JVM赋值了 image.png

image.png

列出被用户或者JVM优化设置过参数

-XX:+PrintCommandLineFlags

image.png

  • 其实就是列出 -XX:+PrintFlagsFinal的结果中第三列有":="的参数

查看正在运行的Java应用程序的扩展参数

jinfo -flag <name> PID

  • 该命令直接查询正在运行指定JVM参数

jinfo -flags PID

  • 该命令直接查询正在运行JVM所有修改过的参数
  • Non-default:已经被JVM自动调整或我们自定义修改的参数,表示不再默认值
  • Command line:我们自定义的命令行参数

1642509135(1).png

通用配置

java -jar -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10m -Xloggc:./gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dump.hprof xxx.jar

注:JVM参数大小设置并没有统一的固定大小,要经过反复业务推算和测试才能慢慢调出适合的参数

参数介绍:

  • -Xms1024m (堆最大大小)
  • -Xmx1024m (堆默认大小)
  • -Xmn256m (新生代大小)
  • -Xss256k (棧最大深度大小)
  • -XX:PermSize (jdk7前永久区大小)
  • -XX:MaxPermGen (jdk7前永久区最大大小)
  • -XX:MetaspaceSize=128m (jdk8后元空间大小)
  • -XX:MaxMetaspaceSize=128m (jdk8后元空间最大大小)
  • -XX:SurvivorRatio=8 (新生代分区比例 8:2)
  • -XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
  • -XX:+PrintGCDetails (打印详细的GC日志)
  • -XX:+PrintGCDateStamps (gc日志输出日期时间戳)
  • -XX:+UseGCLogFileRotation (gc日志文件滚动)
  • -XX:NumberOfGCLogFiles=5 (gc日志文件保留文件数量)
  • -XX:GCLogFileSize=10m (gc日志文件单个尺寸)
  • -Xloggc:./gc.log (gc日志文件保存位置)
  • -XX:+HeapDumpOnOutOfMemoryError (OOM时转储堆信息)
  • -XX:HeapDumpPath=./dump.hprof (堆转储信息保存位置)

使用本地化的内存的好处是什么呢

JDK 8开始把类的元数据放到本地化的堆内存(native heap)中,这一块区域就叫Metaspace,名叫元空间。

最直接的表现就是java.lang.OutOfMemoryError: PermGen 空间问题将不复存在,因为默认的类的元数据分配只受本地内存大小的限制,也就是说本地内存剩余多少,理论上Metaspace就可以有多大,这解决了空间不足的问题。

不过,让Metaspace变得无限大显然是不现实的,因此我们也要限制Metaspace的大小:使用-XX:MaxMetaspaceSize参数来指定Metaspace区域的大小。JVM会默认在运行时根据需要动态地设置MaxMetaspaceSize的大小。

更多参数请参考我之前JVM系列笔记,里面详情介绍了JVM:深入理解JVM(二十一)一一 JVM运行时参数(收藏篇)

写在最后

  • 👍🏻:有收获的,点赞鼓励!
  • ❤️:收藏文章,方便回看!
  • 💬:评论交流,互相进步!