JVM常用参数选项介绍

目录

JVM参数选项类型介绍

标准参数选项

-X参数选项

-XX参数选项

JVM参数选项如何设置

打印设置的XX选项及值

 堆、栈、方法区等内存大小设置

OutofMemory相关的选项

垃圾收集器相关选项

GC日志相关选项

其他参数

通过Java代码获取JVM参数


JVM参数选项类型介绍

关于JDK8的选项参数可以参考官网:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html,另外关于-XX的选项可以看下https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html,官网介绍的很详细,本节不可能把每个参数都做下介绍,只介绍一些常用的,没用过的参数在前面的官方网页上查一下就行,里面注释很详细。

JVM选项分为三种:

  1. 标准选项:比较稳定,后续版本基本不会变化,以-开头
  2. -X选项(非标准选项):以-X开头,一般还是很稳定的,官方说法后续版本可能会出现变更
  3. -XX选项(非标准选项):以-X开头,属于实验性,主要是给JVM开发者用于开发和调试JVM的,在后续的版本中行为有可能会变化

标准参数选项

这类选项的功能是很稳定的,在后续版本中也不太会发生变化。运行java或者java -help可以看到所有的标准选项。所有的标准选项都是以-开头,比如-version,-server,-client等。 

java -version可以查看JDK版本,运行模式(server/client),JIT编译模式等信息。

C:\Users\Administrator>java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

 Hotspot JVM有两种模式,分别是server和client,分别通过-server和-client模式设置

  1. 在32位Windows系统上,不论硬件配置如何,都默认使用Client类型的JVM。其他32位操作系统上,要求机器配置至少有2个以上的CPU和2G以上的内存,则默认会使用Server类型的JVM。 client模式适用于对内存要求较小的桌面应用程序,默认使用Serial串行垃圾收集器
  2. 64位机器上只支持server模式的JVM,适用于需要大内存的应用程序,默认使用并行垃圾收集器

关于server和client的官网介绍为:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html

-X参数选项

这类选项都是以-X开头,可能由于这个原因它们被称为X选项。运行java -X命令可以看到所有的X选项。这类参数的功能还是很稳定,但官方的说法是它们的行为可能会在后续版本中改变,也有可能不在后续版本中提供了。 

JVM的JIT编译模式相关的选项:

  • -Xint表示禁用JIT,所有字节码都被解释执行,这个模式的速度最慢的。
  • -Xcomp表示所有字节码都首先被编译成本地代码,然后再执行。
  • -Xmixed,默认模式,让JIT根据程序运行的情况,有选择地将某些代码编译成本地代码(我们上面执行java -version看到的也是这种默认模式)。

解释执行和编译执行对不同的程序可能有不同的结果,推荐用默认模式。

C:\Users\Administrator>java -Xint -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, interpreted mode)

C:\Users\Administrator>java -Xcomp -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, compiled mode)

C:\Users\Administrator>java -Xmixed -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

 -Xmx -Xms -Xss属于 XX 参数

-Xms<size>        设置初始 Java 堆大小,等价于-XX:InitialHeapSize
-Xmx<size>        设置最大 Java 堆大小,等价于-XX:MaxHeapSize
-Xss<size>        设置 Java 线程堆栈大小,-XX:ThreadStackSize

-XX参数选项

这类选项是属于实验性,主要是给JVM开发者用于开发和调试JVM的,在后续的版本中行为有可能会变化。-XX选项根据是否是boolean类型分为如下两种:

  • Boolean类型格式:-XX:+<name>和-XX:-<name>分别表示启用和禁用 name 属性,例如-XX:+UseG1GC表示启用G1收集器
  • 非Boolean类型格式:非Boolean类型中还分为数值型和非数值型。数值型格式-XX:<option>=<number>,number表示数值,number可以带上单位,比如:'m' / 'M' 表示兆, 'k' /'K' 表示Kb, 'g' / 'G' 表示 g(例如 32k跟32768是一样的效果),例如-XX:NewSize=1024m表示设置新生代初始大小为1024兆。非数值型格式-XX:<name>=<string>,例如:-XX:HeapDumpPath=/usr/local/heapdump.hprof,用来指定heap转存文件的存储路径。

JVM参数选项如何设置

1,开发的时候可以通过eclipse或者Idea工具进行设置。eclipse中配置如下:

2,运行jar包时可以添加JVM参数,java  -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar  demo.jar,

3,通过Tomcat运行war包时,Linux系统下可以在tomcat/bin/catalina.sh中添加类似如下配置 

JAVA_OPTS="-Xms512M -Xmx1024M"

 Windows系统下在catalina.bat中添加类似如下配置

set "JAVA_OPTS=-Xms512M -Xmx1024M"

4,程序运行过程中也可以修改,可以使用jinfo -flag <name>=<value> <pid>设置非Boolean类型参数,可以使用 jinfo -flag [+|-]<name>=<value> <pid>设置Boolean类型参数,pid是进程id。

下面我们介绍一下常用的参数选项。

打印设置的XX选项及值

有三个选项:-XX:+PrintCommandLineFlags、-XX:+PrintFlagsInitial、-XX:+PrintFlagsFinal

  • -XX:+PrintCommandLineFlags可以让在程序运行前打印出用户手动设置或者JVM自动设置的XX选项
  • -XX:+PrintFlagsInitial表示打印出所有XX选项的默认值
  • -XX:+PrintFlagsFinal表示打印出XX选项在运行程序时生效的值

通过执行java -XX:+PrintFlagsFinal -version可以看到如下的参数(太多了没有贴全),我们可以看到UseParNewGC= falseUseParallelGC := true ,输出结果中 = 表示默认值,:= 表示被用户或 JVM 修改后的值

java -XX:+PrintFlagsFinal -version
[Global flags]
    uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
	......
	 bool UseParNewGC                               = false                               {product}
	 bool UseParallelGC                            := true                                {product}
	 bool UseParallelOldGC                          = true                                {product}
	 ......
	uintx YoungPLABSize                             = 4096                                {product}
     bool ZeroTLAB                                  = false                               {product}
     intx hashCode                                  = 5                                   {product}
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

另外,也可以通过 jinfo -flag XX选项名称  <pid>来进行查看运行时的JVM参数,pid是指进程id,可以通过ps -ef|grep java或者jps(jps,jinfo等jdk自带命令下节会介绍)查看,例如下面这样:

C:\Users\Administrator>jps
16084 Bootstrap
11496
18184 Jps
10636
15916

C:\Users\Administrator>jinfo -flag UseParallelGC 15916
-XX:+UseParallelGC

 堆、栈、方法区等内存大小设置

方法区

方法区存放类信息+普通常量+静态常量+编译器编译后的代码等,如果程序中加载的class数量非常多,就需要增加方法区占用内存。

永久代(Java8之前,Java8中没有永久代概念,下面参数无效)

  • -XX:PermSize=256m:设置永久代初始值为256M。
  • -XX:MaxPermSize=256m:设置永久代最大值为256M。

元空间Metaspace(Java8中才有,使用的本地内存)

  • -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集器进行类卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值
  • -XX:MaxMetaspaceSize,最大空间,默认没有限制。
  • -XX:+UseCompressedOops压缩对象指针。 "oops"指的是普通对象指针("ordinary" object pointers),Java堆中对象指针会被压缩成32位。
  • -XX:+UseCompressedClassPointers选项来压缩类指针。对象中指向类元数据的指针(对象头中的class pointer)会被压缩成32位
  • -XX:CompressedClassSpaceSize参数作用是设置Klass Metaspace的大小,默认1G。Klass Metaspace就是用来存klass的,klass是的class文件在jvm里的运行时数据结构。只有当-XX:+UseCompressedClassPointers开启了才有效,但是jdk1.8里是默认开启的,如果这块内存会如果没有满会一直增加。但是如果-Xmx超过了32G,压缩指针是默认不开启的,而这个参数也就失去了设置的意义。

如果开启了-XX:+UseCompressedOops及-XX:+UseCompressedClassesPointers,则UseCompressedOops会使用32-bit的offset来代表java object的引用,而UseCompressedClassPointers则使用32-bit的offset来代表64-bit进程中的class pointer;可以使用CompressedClassSpaceSize来设置这块的空间大小。如果开启了指针压缩,则CompressedClassSpace分配在MaxMetaspaceSize里头,即MaxMetaspaceSize=Compressed Class Space Size + Metaspace area (excluding the Compressed Class Space) Size 

-Xss128k:设置每个线程的栈大小为128k。线程栈的大小会影响到递归调用的深度,同时也会影响到能同时开启的线程数量。在相同物理内存下,减小这个值能生成更多的线程。当这个值被设置的较大(例如>2MB)时将会在很大程度上降低系统的性能。

查看默认的线程栈大小

java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
     intx CompilerThreadStackSize                   = 0               {pd product}        
     intx ThreadStackSize                           = 1024            {pd product}        
     intx VMThreadStackSize                         = 1024            {pd product}      

堆内存

关于堆内存中GC过程,MinorGC,MajorGC,FullGC的区别,《内存分配与回收策略及MinorGC、MajorGC、FullGC介绍》已经介绍过了。

-Xmx3550m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为3550M。

-Xms3550m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为3550M。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。官方推荐配置为整个堆大小的3/8。

-XX:NewSize=1024m:设置年轻代初始值为1024M。

-XX:MaxNewSize=1024m:设置年轻代最大值为1024M。

-XX:SurvivorRatio=8:设置年轻代中Eden区与一个Survivor区的比值,默认为8。

-XX:NewRatio=4:设置老年代与年轻代(包括1个Eden和2个Survivor区)的比值。表示老年代是年轻代的4倍。

-XX:PretenureSizeThreadshold=1024:设置让大于此阈值的对象直接分配在老年代(只对Serial、ParNew收集器有效),单位为字节

-XX:MaxTenuringThreshold=15:默认15,新生代每次MinorGC后,还存活的对象年龄+1,当对象的年龄大于设置的这个值时就进入老年代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。

-XX:+PrintTenuringDistribution:让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布。

-XX:TargetSurvivorRatio 表示MinorGC结束后Survivor区域中占用空间的期望比例。

关于MinorGC有如下两点注意: 

  • 1、如果Survivor中对象的年龄分布显示很多对象在经历了多次GC最终年龄达到了-XX:MaxTenuringThreshold才被移到老年代,这可能说明-XX:MaxTenuringThreshold设置得过大,也有可能是Survivor的空间过大。 
  • 2、如果每次GC后Survivor中对象的大小都没有超过期望的Survivor空间大小,则说明GC工作得很好。反之,则说明可能Survivor空间小了,使得新生成的对象很快就被移到了老年代了。

直接内存

-XX:MaxDirectMemorySize:指定DirectMemory容量,若未指定,则默认与Java堆最大值一样。

OutofMemory相关的选项

如果程序发生了OOM后,可以把内存给dump下来以分析原因,或者自动采取一些别的动作。

  • -XX:+HeapDumpOnOutOfMemoryError 表示在内存出现OOM的时候,把Heap转存(Dump)到文件以便后续分析,文件名通常是java_pid<pid>.hprof,其中pid为该程序的进程号。
  • -XX:HeapDumpPath=<path> 用来指定heap转存文件的存储路径
  • -XX:OnOutOfMemoryError 用来指定一个可行性程序或者脚本的路径,当发生OOM的时候,去执行这个脚本。

下面的命令可以使得在发生OOM的时候,Heap被转存到文件/tmp/heapdump.hprof,同时执行Home目录中的cleanup.sh文件:

 java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp 

垃圾收集器相关选项

关于常用垃圾收集器的参数太多了,请根据自己选用的垃圾收集器选用对应的参数,可以查找开头给的官方文档地址,也可以参考我的上篇博客《常用垃圾收集器介绍》

GC日志相关选项

  • -verbose:gc,输出gc日志信息,默认输出到标准输出
  • -XX:+PrintGC,等同于-verbose:gc 表示打开简化的GC日志

  • -XX:+PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志,并在进程退出时输出当前内存各区域分配情况。

  • -XX:+PrintGCTimeStamps  打印GC发生时相对于JVM启动时的时间。

  • -XX:+PrintGCDateStamps  打印出GC发生的具体时间。

比如,以下是-XX:+PrintGCTimeStamps的输出

0,185: [GC 66048K->53077K(251392K), 0,0977580 secs]
0,323: [GC 119125K->114661K(317440K), 0,1448850 secs]
0,603: [GC 246757K->243133K(375296K), 0,2860800 secs]

以下是两个都打开后的输出:

2014-12-26T17:52:38.613-0800: 3.395: [GC 139776K->58339K(506816K), 0.1442900 secs]
  • -XX:+PrintHeapAtGC  每一次GC前和GC后,都打印堆信息。
  • -XX:+TraceClassLoading  监控类的加载
  • -XX:+PrintGCApplicationStoppedTime 打印GC时线程的停顿时间
  • -XX:+PrintGCApplicationConcurrentTime,垃圾收集之前打印出应用未中断的执行时间
  • -XX:+PrintTenuringDistribution:让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布。
  • -Xloggc:<file> 表示把GC日志写入到一个文件中去,而不是打印到标准输出中。

下面是关于GC日志文件控制相关的参数,设置gc文件滚动和设置滚动日志文件的个数,为了防止单个gc日志文件太大,生产上建议加上

  • -XX:+UseGCLogFileRotation  启用GC日志文件的自动转储
  • -XX:NumberOfGClogFiles=1  GC日志文件的循环数目
  • -XX:GCLogFileSize=1M  控制GC日志文件的大小

其他参数

  • -XX:+DisableExplicitGC,禁止hotspot执行System.gc(),默认禁用;
  • -XX:ReservedCodeCacheSize=<n>[g|m|k]、-XX:InitialCodeCacheSize=<n>[g|m|k],指定代码缓存的大小,用于保存已编译方法生成的本地代码,如果代码缓存被占满JVM会发出警告信息,并切换到interpreted-only模式,JIT编译器被停用,字节码将不会再编译成机器码。这样的话对JVM的性能影响很大;

  • -XX:+UseCodeCacheFlushing,如果代码缓存不断增长导致代码缓存空间不够,使用该参数让jvm放弃一些被编译的代码,避免代码缓存被占满时JVM切换到interpreted-only的情况;

  • -XX:+DoEscapeAnalysis,开启逃逸分析,逃逸分析是一种分析对象范围的技术,在一些情况一个线程分配的对象可能会被其他对象使用,这种现象叫做“逃逸”,如果一个对象没有“逃逸”,则可以运用一些额外的优化技术,这种优化技术“逃逸分析”。通过“逃逸分析” JIT可以使用如下技术优化:

    1. 栈上分配
    2. 消灭同步
    3. 消灭垃圾回收读写障碍
    4. 对象爆炸
  • -XX:+UseBiasedLocking,开启偏向锁,偏向锁是是锁偏爱上次使用它的线程,在非竞争锁的场景下,可以实现无锁的开销。

  • -XX:+UseLargePages,开启使用大页面,使用大页面可以提高TLB(translation lookaside buffer(转换后备缓存区))的缓存命中率;

通过Java代码获取JVM参数

Java提供了java.lang.management包用于监视和管理Java虚拟机和Java运行时中的其他组件,它允许本地和远程监控和管理运行的Java虚拟机。其中ManagementFactory这个类还是挺常用的。另外还有Runtime类也可以获取一些内存、CPU核数等相关的数据。可以通过这些api可以监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理。

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
public class MemoryMonitor {
    public static void main(String[] args) {

        MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
        MemoryUsage usage = memorymbean.getHeapMemoryUsage();
        System.out.println("INIT HEAP: " + usage.getInit() / 1024 / 1024);
        System.out.println("MAX HEAP: " + usage.getMax() / 1024 / 1024);
        System.out.println("USE HEAP: " + usage.getUsed() / 1024 / 1024);
        System.out.println("\nFull Information:");
        System.out.println("Heap Memory Usage: " + memorymbean.getHeapMemoryUsage());
        System.out.println("Non-Heap Memory Usage: " + memorymbean.getNonHeapMemoryUsage());

        System.out.println("=======================通过java来获取相关系统状态============================ ");
        System.out.println("当前堆内存大小totalMemory " + (int) Runtime.getRuntime().totalMemory() / 1024 / 1024 + " M");// 当前堆内存大小
        System.out.println("空闲堆内存大小freeMemory " + (int) Runtime.getRuntime().freeMemory() / 1024 / 1024 + " M");// 空闲堆内存大小
        System.out.println("最大可用总堆内存maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + " M");// 最大可用总堆内存大小


    }
}

 输出如下:

INIT HEAP: 252
MAX HEAP: 3575
USE HEAP: 2

Full Information:
Heap Memory Usage: init = 264241152(258048K) used = 2642440(2580K) committed = 253231104(247296K) max = 3749183488(3661312K)
Non-Heap Memory Usage: init = 2555904(2496K) used = 4229480(4130K) committed = 8060928(7872K) max = -1(-1K)
=======================通过java来获取相关系统状态============================ 
当前堆内存大小totalMemory 241 M
空闲堆内存大小freeMemory 238 M
最大可用总堆内存maxMemory 3575 M

参考:https://www.cnblogs.com/z-sm/p/6253335.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值