JVM常用

JVM 包含多种不同类型的参数选项
-D 用来设置系统属性,属于标准选项
-X 设置非标准选项,支持的选项范围跟具体的 JVM 实现有关
-XX 设置高级选项,允许开发者调整 JVM 的行为、性能、输出调试信息,支持的选项范围也跟具体的 JVM 实现有关
布尔类型的高级选项是起到功能的开关作用,不带参数。使用 + 启用功能,使用 - 禁用功能;对于带参数的高级选项,需要指定参数值
使用 java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version 命令可以查看 JVM 所有的选项

 

1、查看默认初始化 JVM 参数

java -XX:+PrintFlagsInitial -version | grep -iE 'HeapSize'

 查看最终 JVM 参数

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize'

待整理

java -XX:+PrintFlagsInitial -version | grep -iE 'HeapSize'
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize'
java -XX:+UseG1GC -XX:+PrintFlagsFinal -version | grep GCThreads
jstat -gcutil <pid>
jinfo -flags <pid>
jinfo <pid> -flag '-XX:+UseParallelGC'
jstat -gcmetacapacity <pid>
jstat -gcutil <pid>
sudo jhsdb jmap --pid <pid>
jstat -class <pid> 1000 5

  

jvm 参数
含义 参数
堆初始大小 Xms
堆最大大小 -Xmx或-XX:MaxHeapSize=size
新生代大小 -Xmn 或(-XX:NewSize=size + -XX:MaxNewSize=size)
幸存区比例(动态) XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy
幸存区比例 XX:SurvivorRatio=ratio
晋升闯值 XX:MaxTenuringThreshold=threshold
晋升详情 XX:+PrintTenuringDistribution
GC详情 XX:+PrintGCDetails -verbose:gc
FulIGC前 MinorGC XX:+ScavengeBeforeFullGC

 

在较新的Java虚拟机(JVM)版本中,PermSize 和 MaxPermSize 参数已经被弃用并移除。

这是因为自 Java 8 更新 131 起,HotSpot JVM 引入了一项名为 Metaspace 的改进,用于替代永久代(Permanent Generation),并将类元数据存储转移到了本地内存空间。

 

8.查看vm的所有设置参数

#jps查看java进程的pid
jps
#jinfo -flags pid或jcmd pid VM.flags查看vm的所有设置参数
jinfo -flags 14768
jcmd 14768 VM.flags

   

-XX:+PrintFlagsInitial:打印出各个 JVM 参数的默认值。它的输出内容和 -XX:PrintFlagsFinal 类似。

在 OpenJDK 17 中,这两个选项输出行数是一样的,都是 559 行:

$ java -XX:+PrintFlagsInitial -version | wc -l
559
$ java -XX:+PrintFlagsFinal -version | wc -l
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK 64-Bit Server VM (build 17.0.5+8-Ubuntu-2ubuntu120.04, mixed mode, sharing)
559

  

-XX:+PrintCommandLineFlags

-XX:+PrintCommandLineFlags 也是一个非常有用的参数,它可以打印出那些我们通过命令行指定或者 JVM 自动在命令行上设置的参数。

java -XX:+PrintCommandLineFlags -version
-XX:ConcGCThreads=2 -XX:G1ConcRefinementThreads=8 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=62422080 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=998753280 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK 64-Bit Server VM (build 17.0.5+8-Ubuntu-2ubuntu120.04, mixed mode, sharing)  

【实战小记】java启动参数JAVA_OPT不生效问题

 有个项目,启动脚本里面用这个方式启动:

java -jar $MODULER.jar $JAVA_OPT

现象:能正常起来,但是占用内存一直比较高,比较稳定,然后不断调优java_opt的内存参数,但是没效果

 解决:

修改启动顺序如下,内存降下来了
java $JAVA_OPT -jar  $MODULER.jar

 原因:

java启动参数顺序还是有讲究

1) java -jar $MODULER.jar $JAVA_OPT  

因为$JAVA_OPT是没传递给jvm,只是当做jar包的可用参数而存在。所以怎么调优参数值无效果

2)java  $JAVA_OPT  -jar $MODULER.jar

这个是正确的, $JAVA_OPT传递给jvm,在启动的时候生效,内存也降下来了。  

Parallel GC、CMS GC、

  1. 三种GC下,ParallelGCThreads 默认值都是CPU线程数
  2. 并行Parallel GC下:ConcGCThreads = 0
  3. CMS GC下,ConcGCThreads=(ParallelGCThreads+3)/4下取整
  4. G1 GC下,ConcGCThreads=ParallelGCThreads/4四舍五入

G1 GC下验证

最后我们来看一下,把GC换成G1,其他不变,ParallelGCThreads=4,ConcGCThreads=1。

java -XX:+UseG1GC -XX:+PrintFlagsFinal -version | grep GCThreads

测试服务器为 4核8G,所以 ParallelGCThreads = 4

 

这时候就出现一个跟CMS不一样的地方,G1下ConcGCThreads比较小。
CMS: P=5, C=2; P=9, C=3;
G1: P=5, C=1; P=9, C=2;
进一步测试1-12,发现G1下:

    • ParallelGCThreads=1, ConcGCThreads=1; //太小
    • ParallelGCThreads=2-5, ConcGCThreads=1; //C=P/4四舍五入
    • ParallelGCThreads=6-9, ConcGCThreads=2; //C=P/4四舍五入
    • ParallelGCThreads=10-13, ConcGCThreads=3; //C=P/4四舍五入
    • ParallelGCThreads=14-17, ConcGCThreads=4; //C=P/4四舍五入

 

JVM 选项分类
JVM 其实支持三种类型的选项:标准选项(standard options)、非标准选项(non-standard options,又叫 extra-options)和高级选项(advanced options)。之所以有这么多选项,是因为 JVM 只是一个规范,它有不同的实现,例如 HotSpot、OpenJ9、GraalVM、Azul Zing 等。不同的 JVM 实现支持的选项会有所不同,但是有些选项是所有的 JVM 实现都会支持的,这类选项就是标准选项。

 

JVM 包含多种不同类型的参数选项

  • -D 用来设置系统属性,属于标准选项
  • -X 设置非标准选项,支持的选项范围跟具体的 JVM 实现有关
  • -XX 设置高级选项,允许开发者调整 JVM 的行为、性能、输出调试信息,支持的选项范围也跟具体的 JVM 实现有关 
1. java -jar xxx.jar --server.port=8081 
2. java -jar xxx.jar --spring.profiles.active=dev
*这种方式,你打的jar包里得有application-dev.properties或application-dev.yml这类资源文件 
3. java -jar xxx.jar --spring.config.location=D:\Java\application.properties
或 java -jar xxx.jar --spring.config.location=D:\Java\application.yml
*指定加载某个资源文件,也可以使用相对路径 
4. java -jar xxx.jar --spring.config.location=D:\Java\application.properties -Dserver.port=8081 -Dserver.address=127.0.0.1
*扩展,你加载的指定配置文件里的有server.port和server.address配置项

JAVA_OPTS="-Xms256m -Xmx512m -Xss256K  -Djava.security.egd=file:/dev/./urandom  -Dspring.profiles.active=test"
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "

 

分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点。

生成 dump 文件。

1、JVM启动时增加两个参数

# 出现OOME时生成堆dump:
-XX:+HeapDumpOnOutOfMemoryError
# 生成堆文件地址:
-XX:HeapDumpPath=/home/hadoop/dump/

2、jmap生成

发现程序异常前通过执行指令,直接生成当前JVM的dump文件

jmap -dump:file=文件名.dump [pid]
# 9257是指JVM的进程号
jmap -dump:format=b,file=testmap.dump 9257

第一种方式是一种事后方式,需要等待当前JVM出现问题后才能生成dump文件,实时性不高; 第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。

所以建议第一种方式。

 

注意:jhsdb jmap --heap --pid [pid] 异常问题:failed for 1376196: Operation not permitted

 新版的Linux系统(Ubuntu 11.04之后会出现这种问题)加入了 ptrace-scope 机制。这种机制为了防止用户访问当前正在运行的进程的内存和状态,

而一些调试软件本身就是利用 ptrace 来进行获取某进程的内存状态的(包括GDB),所以在新版本的Linux系统,默认情况下不允许再访问了, 可以临时开启(注意权限):

sudo su
echo
0 > /proc/sys/kernel/yama/ptrace_scope

永久修改:

vi /etc/sysctl.d/10-ptrace.conf
kernel.yama.ptrace_scope = 0

 

参考:

JVM常规参数
https://blog.csdn.net/qq_25775675/article/details/131311758

不同GC下ParallelGCThreads和ConcGCThreads的计算公式

https://download.csdn.net/blog/column/10400618/121548143

JVM 监控及诊断工具 - 命令行
https://blog.csdn.net/qq_43530416/article/details/131362585

JVM 参数:`-D`、`-X`、`-XX`
https://blog.csdn.net/nicholas1328/article/details/131316628

JDK 17 之 JVM调优 史诗级 教程
https://blog.csdn.net/qq_44866828/article/details/126309447

JDK命令行(jps、jstat、jinfo、jmap、jhat、jstack、jstatd、hprof)与JConsole
https://blog.csdn.net/bjm20090908/article/details/102701693

JVM jstat命令详解
https://blog.51cto.com/u_12226/6377635

Java进程状况之 jstat 命令
https://blog.csdn.net/qq_29116427/article/details/105912457

JVM | 命令行诊断与调优 jhsdb jmap jstat jps

https://blog.csdn.net/Trollz/article/details/134005964

 

posted @ 2024-02-29 13:37  fieldtianye  阅读(4)  评论(0编辑  收藏  举报