JVM监视与调优

    学习Java GC机制的目的是为了在JVM出现问题时分析原因并解决。JVM监控与调优主要着眼于如何配置、如何监控、如何优化3点。

一、参数配置

    在Java虚拟机的参数中,有3种表示方法,用“ps -ef | grep java”命令,可以得到当前Java进程的所有启动参数和配置参数:

  • 标准参数(-),所有的jvm实现都必须实现这些参数的功能,并且向后兼容;
  • 非标准参数(-X),默认JVM实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;
  • 非Stable参数(-XX),此类参数各个JVM实现都有所不同,将来可能会随时取消,需要慎重使用(但是,这些参数往往是非常有用的);

二、标准参数

    在运行Java命令时后面加上的参数,如java -version,java -jar等,输入命令Java -help或者java -?就能获得当前机器所有Java的标准参数列表。

  • -client:设置Java使用client模式,这是一般在pc机器上使用的模式,启动很快,但性能和内存管理效率并不高;多用于桌面应用;
  • -server:使用server模式,启动速度虽然慢(比client模式慢10%左右),但是性能和内存管理效率很高,适用于服务器,用于生成环境、开发环境或测试环境的服务器;

    如果没有指定-server或-client,JVM启动的时候会自动检测当前主机是否为服务器,如果是就以server模式启动,64位JVM只有server模式,所以无法使用-client参数;默认情况下,不同的启动模式,执行GC的方式有所区别:

启动模式 新生代GC方式 老生代和持久代GC方式
client 串行 串行
server 并行 并发

    如果没有指定-server或-client模式,则判断方法如下:

  • -classpath / -cp:JVM加载和搜索文件的目录路径,多个路径用;分割。注意如果使用了-classpath,JVM就不会再搜索环境变量中定义的CLASSPATH路径。

    JVM搜索路径的顺序为:

  1. 先搜索JVM自带的jar或zip包(Bootstrat,搜索路径可以用System.getProperty("sun.boot.class.path")获得;
  2. 搜索JRE_HOME/lib/ext下的jar包(Extension,搜索路径可以用System.getProperty("java.ext.dirs")获得);
  3. 搜索用户自定义目录,顺序为:当前目录(.),CLASSPATH,-cp;(搜索路径用System.getProperty("java.class.path")获得)
  • -DpropertyName=value:定义系统的全局属性值,如配置文件地址等,如果value有空格,可以用-Dname=“space string”这样的形式来定义,用System.getProperty("propertyName")可以获得这些定义的属性值,在代码中也可以用System.setProperty(""propertyName","value")的形式定义属性。
  • -verbose:这是查询GC问题最常用的命令之一,具体参数如下:①-verbose:class输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可以进行诊断。②-verbose:gc输出每次GC的相关情况。③-verbose:jni输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

二、非标准参数

    非标准参数,是在标准参数的基础上进行扩展的参数,输入“java -X”命令,能获得当前JVM支持的所有非标准参数列表。在不同类型的JVM中,采用的参数有所不同,请参考下图,对内存区域的大小有个形象的了解:

  • -Xmn:新生代内存大小的最大值,包括E区和两个S区的总和。-Xmn只能使用在JDK1.4或之后的版本中,之前的1.3和1.4版本中,可使用-XX:NewSize设置年轻代大小,用-XX:MaxNewSize设置年轻代最大值;如果同时设置了-Xmn和-XX:NewSize,-XX:MaxNewSize,则谁设置在后面,谁就生效;如果同时设置了-XX:newSize  -XX:MaxNewSize与-XX:NewRatio则实际生效的值是:min(MaxNewSize,Max(newSize,Heap/(NewRatio+1))),在开发、测试环境,可以-XX:NewSize和-XX:MaxNewSize来设置新生代大小,但在线上生产环境,使用-Xmn一个即可,或者-XX:NewSize和-XX:MaxNewSize设置为同一个值,这样能够防止在每次GC之后都要调整堆的大小(即:抖动,抖动会严重影响新能)。
  • -Xms:初始堆的大小,也是堆大小的最小值,默认值是总共的物理内存/64(且小于1G),默认情况下,当堆中可用内存小于40%(这个值可以用-XX:MinHeapFreeRatio调整)时,堆内存会开始增加,一直增加到-Xmx的大小;
  • -Xmx:堆的最大值,默认值是总共的物理内存/64(且小于1G),如果Xms和Xmx都不设置,则两者大小会相同,默认情况下,当堆中可用内存大于70%时,堆内存会开始减少,一直减少到-Xms的大小;这个堆的大小=年轻代大小+年老代大小,堆的大小不包括持久代的大小,如果增大了年轻代,年老代会相应减少,官方默认的设置年老代大小/年轻代大小=2/1左右(使用-XX:NewRatio可以设置)。建议在开发测试环境可以用Xms和Xmx分别设置大小值最大值,但是在生产环境上,Xms和Xmx设置的值必须一样,原因与年轻代一样--防止抖动。
  • -Xss:这个参数用于设置每个线程的栈内存,默认1M,一般来说是不需要修改的。除非代码不多,可以设置的小点,另外一个相似的参数是-XX:ThreadStackSize,这两个参数在1.6以前,都是谁设置在后面,谁就生效;1.6版本以后,-Xss设置在后面,则以-Xss为准,-XXThreadStackSize设置在后面,则主线程以-Xss为准,其他线程以-XX:ThreadStackSize为准。
  • -Xrs:减少JVM对操作系统信号的使用,当此参数设置之后,JVM将不接收控制台的控制handler,以防止与在后台以服务形式运行的JVM冲突。
  • -Xprof:跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试;
  • -Xnoclassgc:关闭针对class的gc功能;因为其阻止内存回收,所以可能会导致OutOfMemoryError错误,慎用。
  • -Xincgc:开启增量gc(默认为关闭);这有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应的处理能力。
  • -Xloggc:file:与-verbose:gc功能类似,只是将每次GC事件的相关记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。若与verbose命令同时出现在命令行中,则以-Xloggc为准。

三、非Stable参数(非静态参数)

    以-XX表示的非Stable参数,虽然在官方文档中是不正确的,不健壮的,各个公司的实现也各不相同,但往往非常实用,所以这部分参数对于GC非常重要。JVM(Hotspot)中主要的参数可以大致分为3类:

  • 性能参数(Performance Options):用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;
  • 行为参数(Behavioral Options):用于改变JVM的基础行为,如GC的方法和算法的选择;
  • 调试参数(Debugging Options):用于监控、打印、输出等JVM参数,用于显示JVM更详细的信息;

    对于非Stable参数,使用方法有4种:

  • -XX:+<option>启用选项
  • -XX:-<option>不启用选项
  • -XX:<option>=<number>给选项设置一个数字类型值,可跟单位,例如32k,1024m,2g
  • -XX:<option>=<String>给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

   首先介绍性能参数,性能参数往往用来定义内存分配的大小和比例,相比于行为参数和调试参数。一个比较明显的区别是性能参数后面往往跟的有数值,常用如下:


    常用的行为参数,主要用来选择使用什么样的垃圾收集器组合,以控制运行中的GC策略。


     常用的调试参数,用于监控和打印GC的信息:


     这些参数将为我们进行GC的监控与调试提供很大帮助,是我们进行GC相关操作的重要工具。 

 

 

转自:http://www.cnblogs.com/zhguang/p/Java-JVM-GC.html

猜你喜欢

转载自student-lp.iteye.com/blog/2341423