JVM优化系列-------[1丶jvm的三种运行参数]

我们为什么要对jvm进行优化

在本地开发环境中我们很少会遇到需要对jvm进行优化的需求,但是到了生产环境,我们可能将有下面的需求:

  • 运行的应用“卡住了”,日志不输出,程序没有反应
  • 服务器的CPU负载突然升高
  • 在多线程应用下,如何分配线程的数量?

在本系类文章中,我将对jvm进行深入的讲解,我们不仅要让程序能跑起来,而且是可以跑的更快!可以分析解决在生产环境中所遇到的各种“棘手”的问题,其中运行的代码和程序建议小伙伴们和墨白一起动手敲敲。

(说明:本系列文章使用的jdk版本Windows为1.8,Linux是1.9)

  • 了解jvm的运行参数

在jvm中有很多的参数可以进行设置,这样可以让jvm在各种环境中都能够高效的运行。绝大部分的参数保持默认即可。

jvm的参数类型分为三类,分别是:

 1标准参数
 2-help
 3-version
 4-X参数 (非标准参数)
 5-Xint
 6-Xcomp
 7-XX参数(使用率较高)
 8-XX:newSize
 9-XX:+UseSerialGC

我们可以用java-命令挨个测试这些参数

1. 标准参数

jvm的标准参数,一般都是很稳定的,在未来的JVM版本中不会改变,可以使用java -help

检索出所有的标准参数。

 1[root@localhost ~]# java -help
 2用法: java [options] <主类> [args...]
 3           (执行类)
 4   或  java [options] -jar <jar 文件> [args...]
 5           (执行 jar 文件)
 6   或  java [options] -m <模块>[/<主类>] [args...]
 7       java [options] --module <模块>[/<主类>] [args...]
 8           (执行模块中的主类)
 9
10 将主类, -jar <jar 文件>, -m 或 --module
11 <模块>/<主类> 后的参数作为参数传递到主类。
12
13 其中, 选项包括:
14
15    -d32      已过时, 在以后的发行版中将被删除
16    -d64      已过时, 在以后的发行版中将被删除
17    -cp <目录和 zip/jar 文件的类搜索路径>
18    -classpath <目录和 zip/jar 文件的类搜索路径>
19    --class-path <目录和 zip/jar 文件的类搜索路径>
20                  使用 : 分隔的, 用于搜索类文件的目录, JAR 档案
21                  和 ZIP 档案列表。
22    -p <模块路径>
23    --module-path <模块路径>...
24                  用 : 分隔的目录列表, 每个目录
25                  都是一个包含模块的目录。
26    --upgrade-module-path <模块路径>...
27                  用 : 分隔的目录列表, 每个目录
28                  都是一个包含模块的目录, 这些模块
29                  用于替换运行时映像中的可升级模块
30    --add-modules <模块名称>[,<模块名称>...]
31                  除了初始模块之外要解析的根模块。
32                  <模块名称> 还可以为 ALL-DEFAULT, ALL-SYSTEM,
33                  ALL-MODULE-PATH.
34    --list-modules
35                  列出可观察模块并退出
36    -d <module name>
37    --describe-module <模块名称>
38                  描述模块并退出
39    --dry-run     创建 VM 并加载主类, 但不执行 main 方法。
40                  此 --dry-run 选项对于验证诸如
41                  模块系统配置这样的命令行选项可能非常有用。
42    --validate-modules
43                  验证所有模块并退出
44                  --validate-modules 选项对于查找
45                  模块路径中模块的冲突及其他错误可能非常有用。
46    -D<名称>=<值>
47                  设置系统属性
48    -verbose:[class|module|gc|jni]
49                  启用详细输出
50    -version      将产品版本输出到错误流并退出
51    --version     将产品版本输出到输出流并退出
52    -showversion  将产品版本输出到错误流并继续
53    --show-version
54                  将产品版本输出到输出流并继续
55    --show-module-resolution
56                  在启动过程中显示模块解析输出
57    -? -h -help
58                  将此帮助消息输出到错误流
59    --help        将此帮助消息输出到输出流
60    -X            将额外选项的帮助输出到错误流
61    --help-extra  将额外选项的帮助输出到输出流
62    -ea[:<程序包名称>...|:<类名>]
63    -enableassertions[:<程序包名称>...|:<类名>]
64                  按指定的粒度启用断言
65    -da[:<程序包名称>...|:<类名>]
66    -disableassertions[:<程序包名称>...|:<类名>]
67                  按指定的粒度禁用断言
68    -esa | -enablesystemassertions
69                  启用系统断言
70    -dsa | -disablesystemassertions
71                  禁用系统断言
72    -agentlib:<库名>[=<选项>]
73                  加载本机代理库 <库名>, 例如 -agentlib:jdwp
74                  另请参阅 -agentlib:jdwp=help
75    -agentpath:<路径名>[=<选项>]
76                  按完整路径名加载本机代理库
77    -javaagent:<jar 路径>[=<选项>]
78                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
79    -splash:<图像路径>
80                  使用指定的图像显示启动屏幕
81                  自动支持和使用 HiDPI 缩放图像
82                  (如果可用)。应始终将未缩放的图像文件名 (例如, image.ext)
83                  作为参数传递给 -splash 选项。
84                  将自动选取提供的最合适的缩放
85                  图像。
86                  有关详细信息, 请参阅 SplashScreen API 文档
87    @argument 文件
88                  一个或多个包含选项的参数文件
89    -disable-@files
90                  阻止进一步扩展参数文件
91要为长选项指定参数, 可以使用 --<名称>=<值> 或
92--<名称> <值>。
  • 查看jvm的版本
1 [root@localhost ~]# java -version
2 java version "9.0.4"
3 Java(TM) SE Runtime Environment (build 9.0.4+11)
4 Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
  • 通过-D设置系统属性参数
 1package com.mobaijun.jvm;
 2
 3/**
 4 * @Author:Auser·杰
 5 * @DATE:2019/10/8 23:27
 6 */
 7public class TestJVM {
 8  public static void main(String[] args) {
 9    String str = System.getProperty("str");
10    if (str == null){
11      System.out.println("mobaijun");
12    }else {
13      System.out.println(str);
14    }
15  }
16}

结果:

用Linux编译运行,通过-D设置属性参数

 1== 根目录下创建test文件夹存放java文件
 2[root@localhost ~]# mkdir test
 3== 查看目录内容
 4[root@localhost ~]# ll
 5总用量 2
 6drwxr-xr-x. 2 root root    6 10月  8 23:57 test
 7== 进入test目录
 8[root@localhost ~]# cd test
 9== vim命令创建TestJVM.java文件,复制刚刚写的代码,esc返回,shift+:,输入wq保存
10[root@localhost test]# vim TestJVM.java
11== 编译class文件
12[root@localhost test]# javac TestJVM.java 
13[root@localhost test]# ll
14总用量 8
15-rw-r--r--. 1 root root 575 10月  8 23:58 TestJVM.class
16-rw-r--r--. 1 root root 225 10月  8 23:58 TestJVM.java
17== 运行
18[root@localhost test]# java  TestJVM
19mobaijun
20== 通过-D设置属性参数
21[root@localhost test]# java -Dstr=nihaojvm TestJVM
22== 运行结果
23nihaojvm
  • -server与-client参数

可以通过-server或-client设置jvm的运行参数。

  • 它们的区别是Server VM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
  • Client VM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,它的目标是为了让JVM的启动速度更快,但运行速度会比Serverm模式慢些。
  • JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的JVM。

32位操作系统

1.如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。

2.如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默认使用server模式,否则使用client模式。

64位操作系统

1.只有server类型,不支持client类型。

【运行测试】

 1[root@localhost test]# java -client -showversion TestJVM
 2java version "9.0.4"
 3Java(TM) SE Runtime Environment (build 9.0.4+11)
 4Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
 5mobaijun
 6[root@localhost test]# java -server -showversion TestJVM
 7java version "9.0.4"
 8Java(TM) SE Runtime Environment (build 9.0.4+11)
 9Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
10mobaijun

2. X参数

jvm的-X参数是非标准参数,在不同版本的jvm中,参数可能会有所不同,可以通过java -X查看非标准参数。

 1[root@localhost test]# java -X
 2
 3    -Xbatch           禁用后台编译
 4    -Xbootclasspath/a:<directories and zip/jar files separated by :>
 5                      附加在引导类路径末尾
 6    -Xcheck:jni       对 JNI 函数执行其他检查
 7    -Xcomp            在首次调用时强制编译方法
 8    -Xdebug           为实现向后兼容而提供
 9    -Xdiag            显示附加诊断消息
10    -Xfuture          启用最严格的检查, 预期将来的默认值
11    -Xint             仅解释模式执行
12    -Xinternalversion
13                      显示比 -version 选项更详细的 JVM
14                      版本信息
15    -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
16    -Xmixed           混合模式执行 (默认值)
17    -Xmn<size>        为年轻代 (新生代) 设置初始和最大堆大小
18                      (以字节为单位)
19    -Xms<size>        设置初始 Java 堆大小
20    -Xmx<size>        设置最大 Java 堆大小
21    -Xnoclassgc       禁用类垃圾收集
22    -Xprof            输出 cpu 分析数据 (已过时)
23    -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
24    -Xshare:auto      在可能的情况下使用共享类数据 (默认值)
25    -Xshare:off       不尝试使用共享类数据
26    -Xshare:on        要求使用共享类数据, 否则将失败。
27    -XshowSettings    显示所有设置并继续
28    -XshowSettings:all
29                      显示所有设置并继续
30    -XshowSettings:locale
31                      显示所有与区域设置相关的设置并继续
32    -XshowSettings:properties
33                      显示所有属性设置并继续
34    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
35    -Xss<size>        设置 Java 线程堆栈大小
36    -Xverify          设置字节码验证器的模式
37    --add-reads <module>=<target-module>(,<target-module>)*
38                      更新 <module> 以读取 <target-module>, 而无论
39                      模块声明如何。
40                      <target-module> 可以是 ALL-UNNAMED 以读取所有未命名
41                      模块。
42    --add-exports <module>/<package>=<target-module>(,<target-module>)*
43                      更新 <module> 以将 <package> 到处到 <target-module>,
44                      而无论模块声明如何。
45                      <target-module> 可以是 ALL-UNNAMED 以导出到所有
46                      未命名模块。
47    --add-opens <module>/<package>=<target-module>(,<target-module>)*
48                      更新 <module> 以在 <target-module> 中打开
49                      <package>, 而无论模块声明如何。
50    --illegal-access=<value>
51                      允许或拒绝通过未命名模块中的代码对命名模块中的
52                      类型成员进行访问。
53                      <value> 为 "deny", "permit", "warn" 或 "debug" 之一
54                      此选项将在未来发行版中删除。
55    --limit-modules <module name>[,<module name>...]
56                      限制可观察模块的领域
57    --patch-module <module>=<file>(:<file>)*
58                      使用 JAR 文件或目录中的类和资源
59                      覆盖或增强模块。
60    --disable-@files 禁止进一步扩展参数文件
61
62这些额外选项如有更改, 恕不另行通知。
  • 了解-Xint、-Xcomp、-Xmixed参数

在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度,通常低10倍或更多。

-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。

然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有让JVM启用JIT编译器的全部功能。JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就没有意义了。

-Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是jvm默认的模式,也是推荐使用的模式。

比方强制设置运行模式:

 1== 强制设置为解释模式
 2[root@localhost test]# java -showversion -Xint TestJVM
 3java version "9.0.4"
 4Java(TM) SE Runtime Environment (build 9.0.4+11)
 5Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, interpreted mode)
 6mobaijun
 7== 强制设置为编译模式
 8== 需要注意的是:编译模式下,第一次执行速度会比解释模式下执行速度慢一些,需要注意观察。
 9[root@localhost test]# java -showversion -Xcomp TestJVM
10java version "9.0.4"
11Java(TM) SE Runtime Environment (build 9.0.4+11)
12Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, compiled mode)
13mobaijun
14== 默认的混合模式
15[root@localhost test]# java -showversion TestJVM
16java version "9.0.4"
17Java(TM) SE Runtime Environment (build 9.0.4+11)
18Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
19mobaijun

3. -XX参数

-XX参数也是非标准参数,主要用于jvm的调优和debug操作。

-XX参数的使用有2种方式,一种是boolean类型,一种是非boolean类型:

boolean类型

格式:-XX:[+-]

如:-XX:+DisableExplicitGC 表示禁用手动调用gc操作,也就是说调用

System.gc()无效

非boolean类型

格式:-XX:

如:-XX:NewRatio=1 表示新生代和老年代的比值

测试:

1[root@localhost test]# java -showversion -XX:+DisableExplicitGC TestJVM
2java version "9.0.4"
3Java(TM) SE Runtime Environment (build 9.0.4+11)
4Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
5mobaijun

4. -Xms与-Xmx参数

1.-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。

2.-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。

3.-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。

4.适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。

测试:

1== 可以很明显的感觉到输出速度变快了
2[root@localhost test]# java -Xms512m -Xmx2048m TestJVM
3mobaijun

本文分享自微信公众号 - 框架师(mohu121)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏光城(guangcity)

TensorFlow线性回归与逻辑回归实战

Huber loss是为了增强平方误差损失函数(squared loss function)对噪声(或叫离群点,outliers)的鲁棒性提出的。

14130
来自专栏测试开发社区

django--ajax的使用,应用

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服...

9340
来自专栏光城(guangcity)

回归Android,继续刷题

这两天要做个安卓项目,哎,我之前是做安卓开发的,做了半年多,后面就没做了,距离现在至少1年半有余。

12130
来自专栏吉林乌拉

设计模式之观察者模式

今天我继续和大家分享一下设计模式中的知识,今天我们来看一下观察者模式。观察者模式也可以叫发布订阅模式,在实际的场景中有很多时候会遇到这种设计模式。在现实的生活中...

7830
来自专栏沉默王二

Java 并发编程(三):如何保证共享变量的可见性?

上一篇,我们谈了谈如何通过同步来保证共享变量的原子性(一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行),本篇我们来谈一谈如何保...

10430
来自专栏路人甲Java

玩转Mysql系列 - 第11篇:深入了解连接查询及原理

当我们查询的数据来源于多张表的时候,我们需要用到连接查询,连接查询使用率非常高,希望大家都务必掌握。

8020
来自专栏光城(guangcity)

Hadoop3.x伪分布式及Hbase搭建与单词统计项目构建

本节从0开始一步步搭建伪分布式及Hbase等。同时学习使用Intellij Maven构建Map-Reduce项目进行单词统计。

13040
来自专栏Java后端技术栈cwnait

如何理解数组在Java中作为一个类?【完整版】

Java中数组的使用方法和C/C++中的比较类似,但是在Java中它的本质是一个Java类,只是这个类比较特殊,所以很容易被一些程序员误解。建议在回答该问题的时...

10730
来自专栏光城(guangcity)

matlibplot绘制各种图形

0.导语1.预备知识1.1 np.arange()1.2 numpy.random.uniform()1.3 zip()2.bar绘制3.散点图4.3D图5.参...

16850
来自专栏光城(guangcity)

python进阶之异步任务

本文学习视频来自莫凡python,下面是总结的学习内容。 关于星球,我在稍微阐述一点,我用自己的精力在星球中发布小项目,发布日打卡,共同来学习某一块知识,所以改...

6520

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励