实用Java虚拟机参数

-Xmx50m 设置最大内存为50兆

-Xms30m 设置最小内存为30兆

-Xmn10m 设置年轻代内存大小为10兆,年轻代包括一个Eden和两个Survivor区。

-XX:+HeapDumpOnOutOfMemoryError 在出现内存溢出异常(OOME)时自动生成转储文件,后缀名为hprof,路径为执行程序的所在路径。也可以通过-XX:HeapDumpPath指定路径。

-XX:+UseTLAB启用本地线程分配缓冲Thread Local Allocation Buffer

-XX:SurvivorRatio=6设置年轻代中Eden区的本例,这里是6:1:1(Eden:Survivor0:Survivor1)。默认JDK8的收集器是Parallel Scavenge,而且其UseAdaptiveSizePolicy参数是默认开启的,想关都关不了。这个参数会优先保证吞吐量,自动调整新生代和老年代的大小,这种情况下SurvivorRatio无效。

-Xss128k 虚拟机栈空间设置为128K。单线程模式下,占空间过小,可能导致StackOverflowError异常。多线程模式下,可能导致OOME异常。

-XX:PermSize方法区空间,方法区也可以称之为元数据区

-XX:MaxPermSize 方法区最大空间

有一个经验值得关注。如果发现Full GC频繁发生在空间扩容上,可以将-Xms与-Xmx保持一致,并且将-XX:PermSize与-XX:MaxPermSize也设置同样的值。避免多次动态扩展浪费的时间。

 

-verbose:class 显示类加载的详细信息。要么从文件夹的.class直接加载,要么从jar。

-verbose:gc输出内存回收的细节。其中Serial收集器的新生代名字为DefNew;ParNew收集器的新生代名字为ParNew;Parallel Scavenge的新生代名字为PSYoungGen。

-XX:MaxGCPauseMillis 设置MinorGC的最大完成时间。是否需要配合-XX:+UseParallelGC参数?我的实验表明,JDK8默认是采用的Parallel Scavenge收集器。

-XX:GCTimeRatio 设置垃圾回收时间占总时间的比例,0-100之间。例如设置为19,那么最大GC时间的比例是1/(1+19)。默认值为99,那么垃圾回收时间是1/(1+99) ,也就是说1%的时间允许用在GC上。由于与吞吐量关系密切,ParallelScavenge收集器也经常称为“吞吐量优先”收集器。除上述两个参数之外,ParallelScavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得关注。这是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略。如果读者对于收集器运作原来不太了解,手工优化存在困难的时候,使用ParallelScavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成将是一个不错的选择。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio(更关注吞吐量)参数给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是ParallelScavenge收集器与ParNew收集器的一个重要区别。

 

-XX:+UseParNewGC 启用ParNew收集器

-XX:+UseParallelGC 启用Parallel Scavenge收集器,实际上这是JDK8的默认值

-XX:+UseConcMarkSweepGC 启用CMS收集器

-XX:+UseG1GC  启用G1收集器

-XX:+UseSerialGC  启用Serial收集器,回收时会StopTheWorld

 

Parallel Scavenge目标是提高吞吐量,即尽量保证CPU的时间用在用户线程上,而不是垃圾回收上。

而CMS的目标是,控制每一次GC的停顿时间,让用户流畅的使用系统。G1的目的是充分利用多核优势,减少STOP THE WORLD停顿时间。目前公开测试的结果来看,G1没有CMS好。

经常看到-XX:+UseConcMarkSweepGC 与 -XX:+UseParNewGC结合起来使用。但是CMS收集器的默认新生代收集器就是ParNew,所以后面的参数其实加不加都无所谓。

 

-XX:PretenureSizeThreshold=3145728 设置直接进入老年代的大对象(3M)大小。可以考虑ParNew+CMS的组合。

 

-XX:MaxTenuringThreshold=15 决定从年轻代移动到老年代的年龄阈值(熬过一次Minor年龄+1)。如果Survivor空间中同年龄对象达到空间的一半以上,年龄在此之上的所有对象,直接进入老年代,忽略MaxTenuringThreshold的限制。
-XX:+PrintTenuringDistribution 日志中输出年龄空间占用等详细信息

-XX:+HeapDumpOnCtrlBreak 可以试用Ctrl+Break键让虚拟机生成dump文件

-Xverfiy:none 取消字节码校验

-server 服务器模式,启动速度慢,运行速度快,采用C2编译器

-client客服端模式,启动快,运行慢,采用C1编译器

-Xnoclassgc

关闭CLASS的垃圾回收功能,就是虚拟机加载的类,即便是不使用,没有实例也不会回收。如果一个类20分钟还没有使用,虚拟机会卸载这个类。如果这个类再次使用,虚拟机会重新加载这个类,由于虚拟机加载类包含了IO和内存分配的操作,因此加载时会对性能有所影响。对于一般应用,这个参数对性能影响不大。

-XX:CMSInitiatingOccupancyFraction=80默认CMS是在tenured generation满68%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值 ,例如本例80%。
 

默认情况下,虚拟机运行于混合模式(Mixed Mode),即大部分通过字节码解释执行,需要时把字节码编译为操作系统环境下的本地执行程序。

-Xint 强制虚拟机运行于“解释模式”(Interpreted Mode)

-Xcomp 强制虚拟机运行于“编译模式”(Compiled Mode)

 

Java内存模型,把内存划分为主内存和工作内存。主内存对应进程,工作内存对应线程。主内存支持lock、unlock、read、write操作,工作内存支持load、store、use、assign操作。如果要把一个变量从主内存复制到工作内存,那就要顺序地执行read和load操作,如果要把变量从工作内存同步回主内存,就要顺序地执行store和write操作。

-XX:+PrintInlining要求虚拟机输出方法内联信息

-XX:+PrintCompilation要求虚拟机在即时编译时将被编译成本地代码的方法名称打印出来

-XX:+UseSpinning 开启自旋锁。在锁占用时间非常短的情况下,减少线程频繁挂起恢复的开销。

-XX:PreBlockSpin 设置自旋锁尝试的次数,默认值为10。据说JDK1.7后,去掉此参数,由JVM控制,待验证。

 

其他工具:

jstat -gccause 8456 查看GC的原因。8456是进程编号。

 

 

 

 

 

 

 

你可能感兴趣的:(Java)