前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM优化系列-------[1丶jvm的三种运行参数]

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

作者头像
田维常
发布2019-10-11 14:55:08
1.5K0
发布2019-10-11 14:55:08
举报
文章被收录于专栏:Java后端技术栈cwnait

正文

引言:

最近墨白在学习jvm优化相关的技术,所以我准备出一个jvm优化系列的文章,最近也是比较忙,抽空我就会更新,文章内有代码和命令建议大家手敲增加印象,最好能理解,不明白的可以后台留言或者在群里提问;

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

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

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

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

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

  • 了解jvm的运行参数

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

  • jvm的参数类型分为三类,分别是:
代码语言:javascript
复制
标准参数
-help
-version
-X参数 (非标准参数)
-Xint
-Xcomp
-XX参数(使用率较高)
-XX:newSize
-XX:+UseSerialGC

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

  • 标准参数

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

检索出所有的标准参数。

代码语言:javascript
复制
 [root@localhost ~]# java -help
用法: java [options] <主类> [args...]
           (执行类)
   或  java [options] -jar <jar 文件> [args...]
           (执行 jar 文件)
   或  java [options] -m <模块>[/<主类>] [args...]
       java [options] --module <模块>[/<主类>] [args...]
           (执行模块中的主类)

 将主类, -jar <jar 文件>, -m 或 --module
 <模块>/<主类> 后的参数作为参数传递到主类。

 其中, 选项包括:

    -d32      已过时, 在以后的发行版中将被删除
    -d64      已过时, 在以后的发行版中将被删除
    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
    --class-path <目录和 zip/jar 文件的类搜索路径>
                  使用 : 分隔的, 用于搜索类文件的目录, JAR 档案
                  和 ZIP 档案列表。
    -p <模块路径>
    --module-path <模块路径>...
                  用 : 分隔的目录列表, 每个目录
                  都是一个包含模块的目录。
    --upgrade-module-path <模块路径>...
                  用 : 分隔的目录列表, 每个目录
                  都是一个包含模块的目录, 这些模块
                  用于替换运行时映像中的可升级模块
    --add-modules <模块名称>[,<模块名称>...]
                  除了初始模块之外要解析的根模块。
                  <模块名称> 还可以为 ALL-DEFAULT, ALL-SYSTEM,
                  ALL-MODULE-PATH.
    --list-modules
                  列出可观察模块并退出
    -d <module name>
    --describe-module <模块名称>
                  描述模块并退出
    --dry-run     创建 VM 并加载主类, 但不执行 main 方法。
                  此 --dry-run 选项对于验证诸如
                  模块系统配置这样的命令行选项可能非常有用。
    --validate-modules
                  验证所有模块并退出
                  --validate-modules 选项对于查找
                  模块路径中模块的冲突及其他错误可能非常有用。
    -D<名称>=<值>
                  设置系统属性
    -verbose:[class|module|gc|jni]
                  启用详细输出
    -version      将产品版本输出到错误流并退出
    --version     将产品版本输出到输出流并退出
    -showversion  将产品版本输出到错误流并继续
    --show-version
                  将产品版本输出到输出流并继续
    --show-module-resolution
                  在启动过程中显示模块解析输出
    -? -h -help
                  将此帮助消息输出到错误流
    --help        将此帮助消息输出到输出流
    -X            将额外选项的帮助输出到错误流
    --help-extra  将额外选项的帮助输出到输出流
    -ea[:<程序包名称>...|:<类名>]
    -enableassertions[:<程序包名称>...|:<类名>]
                  按指定的粒度启用断言
    -da[:<程序包名称>...|:<类名>]
    -disableassertions[:<程序包名称>...|:<类名>]
                  按指定的粒度禁用断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<库名>[=<选项>]
                  加载本机代理库 <库名>, 例如 -agentlib:jdwp
                  另请参阅 -agentlib:jdwp=help
    -agentpath:<路径名>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jar 路径>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<图像路径>
                  使用指定的图像显示启动屏幕
                  自动支持和使用 HiDPI 缩放图像
                  (如果可用)。应始终将未缩放的图像文件名 (例如, image.ext)
                  作为参数传递给 -splash 选项。
                  将自动选取提供的最合适的缩放
                  图像。
                  有关详细信息, 请参阅 SplashScreen API 文档
    @argument 文件
                  一个或多个包含选项的参数文件
    -disable-@files
                  阻止进一步扩展参数文件
要为长选项指定参数, 可以使用 --<名称>=<值> 或
--<名称> <值>。
  • 查看jvm的版本
代码语言:javascript
复制
[root@localhost ~]# java -version
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
  • 通过-D设置系统属性参数
代码语言:javascript
复制
package com.mobaijun.jvm;

/**
 * @Author:Auser·杰
 * @DATE:2019/10/8 23:27
 */
public class TestJVM {
  public static void main(String[] args) {
    String str = System.getProperty("str");
    if (str == null){
      System.out.println("mobaijun");
    }else {
      System.out.println(str);
    }
  }
}

结果:

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

代码语言:javascript
复制
== 根目录下创建test文件夹存放java文件
[root@localhost ~]# mkdir test
== 查看目录内容
[root@localhost ~]# ll
总用量 2
drwxr-xr-x. 2 root root    6 10月  8 23:57 test
== 进入test目录
[root@localhost ~]# cd test
== vim命令创建TestJVM.java文件,复制刚刚写的代码,esc返回,shift+:,输入wq保存
[root@localhost test]# vim TestJVM.java
== 编译class文件
[root@localhost test]# javac TestJVM.java 
[root@localhost test]# ll
总用量 8
-rw-r--r--. 1 root root 575 10月  8 23:58 TestJVM.class
-rw-r--r--. 1 root root 225 10月  8 23:58 TestJVM.java
== 运行
[root@localhost test]# java  TestJVM
mobaijun
== 通过-D设置属性参数
[root@localhost test]# java -Dstr=nihaojvm TestJVM
== 运行结果
nihaojvm
  • -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类型。

运行测试

代码语言:javascript
复制
[root@localhost test]# java -client -showversion TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
mobaijun
[root@localhost test]# java -server -showversion TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
mobaijun
  • X参数

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

代码语言:javascript
复制
[root@localhost test]# java -X

    -Xbatch           禁用后台编译
    -Xbootclasspath/a:<directories and zip/jar files separated by :>
                      附加在引导类路径末尾
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xcomp            在首次调用时强制编译方法
    -Xdebug           为实现向后兼容而提供
    -Xdiag            显示附加诊断消息
    -Xfuture          启用最严格的检查, 预期将来的默认值
    -Xint             仅解释模式执行
    -Xinternalversion
                      显示比 -version 选项更详细的 JVM
                      版本信息
    -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
    -Xmixed           混合模式执行 (默认值)
    -Xmn<size>        为年轻代 (新生代) 设置初始和最大堆大小
                      (以字节为单位)
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xnoclassgc       禁用类垃圾收集
    -Xprof            输出 cpu 分析数据 (已过时)
    -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
    -Xshare:auto      在可能的情况下使用共享类数据 (默认值)
    -Xshare:off       不尝试使用共享类数据
    -Xshare:on        要求使用共享类数据, 否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:all
                      显示所有设置并继续
    -XshowSettings:locale
                      显示所有与区域设置相关的设置并继续
    -XshowSettings:properties
                      显示所有属性设置并继续
    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
    -Xss<size>        设置 Java 线程堆栈大小
    -Xverify          设置字节码验证器的模式
    --add-reads <module>=<target-module>(,<target-module>)*
                      更新 <module> 以读取 <target-module>, 而无论
                      模块声明如何。
                      <target-module> 可以是 ALL-UNNAMED 以读取所有未命名
                      模块。
    --add-exports <module>/<package>=<target-module>(,<target-module>)*
                      更新 <module> 以将 <package> 到处到 <target-module>,
                      而无论模块声明如何。
                      <target-module> 可以是 ALL-UNNAMED 以导出到所有
                      未命名模块。
    --add-opens <module>/<package>=<target-module>(,<target-module>)*
                      更新 <module> 以在 <target-module> 中打开
                      <package>, 而无论模块声明如何。
    --illegal-access=<value>
                      允许或拒绝通过未命名模块中的代码对命名模块中的
                      类型成员进行访问。
                      <value> 为 "deny", "permit", "warn" 或 "debug" 之一
                      此选项将在未来发行版中删除。
    --limit-modules <module name>[,<module name>...]
                      限制可观察模块的领域
    --patch-module <module>=<file>(:<file>)*
                      使用 JAR 文件或目录中的类和资源
                      覆盖或增强模块。
    --disable-@files 禁止进一步扩展参数文件

这些额外选项如有更改, 恕不另行通知。
  • 了解-Xint、-Xcomp、-Xmixed参数

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

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

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

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

比方强制设置运行模式:

代码语言:javascript
复制
== 强制设置为解释模式
[root@localhost test]# java -showversion -Xint TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, interpreted mode)
mobaijun
== 强制设置为编译模式
== 需要注意的是:编译模式下,第一次执行速度会比解释模式下执行速度慢一些,需要注意观察。
[root@localhost test]# java -showversion -Xcomp TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, compiled mode)
mobaijun
== 默认的混合模式
[root@localhost test]# java -showversion TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
mobaijun
  • -XX参数

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

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

boolean类型

格式:-XX:[+-]

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

System.gc()无效

非boolean类型

格式:-XX:

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

测试:

代码语言:javascript
复制
[root@localhost test]# java -showversion -XX:+DisableExplicitGC TestJVM
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
mobaijun
  • -Xms与-Xmx参数

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

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

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

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

测试:

代码语言:javascript
复制
== 可以很明显的感觉到输出速度变快了
[root@localhost test]# java -Xms512m -Xmx2048m TestJVM
mobaijun
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
应用安全开发
应用安全开发(Application Security Development,下文中也叫 Xcheck)为您提供优质的代码分析服务。Xcheck 凭借优秀的算法和工程实现,能在极低的误报率和漏报率前提下,以极快的速度发现代码中存在的安全漏洞。Xcheck 采用私有化部署的模式,所以产品使用的整个生命周期,源码都不会流出公司网络,杜绝源码泄露风险。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档