Sun出品的Hotspot VM提供了丰富的命令行选项用于定制JVM的行为,这篇文章用来记录内存管理相关的部分,但是选项太多了,我本人用到的只是少数,因此这里记录的也仅仅是其中的一部分。
基础知识
GC,全称Garbage Collection,直译是垃圾回收,其实就是管理内存,收集当前失效对象占用的内存,重新使这部分内存变为可用。
Hotspot VM提供的定制选项多以-X或者-XX开头,文档中指出这些选项并不是Java标准的一部分,因而这些选项在其它公司开发的JVM中可能是不存在的,在切换不同公司的JVM时要特别注意。对于-XX开头的选项,Hotspot VM有如下的分类,对于取值为布尔类型的选项,使用-XX:+<option>表示启用选项,使用-XX:-<option>表示禁用选项;对于取值为数值类型的选项,使用-XX:<option>=<number>方式来指定选项的值;对于取值为字符串类型的选项,使用-XX:<option>=<string>来指定选项的值。
GC算法
-XX:+UseConcMarkSweepGC 针对老生代,启用CMS算法的并发回收器。
-XX:+UseParNewGC 称为parallel copying collector,可以配合CMS使用,针对新生代应用的并行复制回收器。
-XX:+UseParallelGC 称为parallel scavenge collector,针对新生代使用的并行回收器。
-XX:-UseParallelOldGC 配合选项-XX:+UseParallelGC使用,对老生代也启用并行收集。
-XX:-UseSerialGC 最原始的单线程回收器,在某些场景下仍有用武之地。
-XX:+UseG1GC Java 7的默认回收器,目前项目开发中还没有机会使用,等以后G1发展成熟了再考虑使用,体验一下高端垃圾回收器的优越性。
内存空间分配
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程栈的大小。
-XX:NewRatio=n 新生代占用空间与年老代空间的比例,如取值为4,则表示年轻代与年老代比例为1:4。
-XX:MaxTenuringThreshold=n 表示一个对象如果在新生代的Eden区和Survivor区之间移动次数超过n次,就直接移动至老生代。
-XX:NewSize=2m 表示新生代占用的空间,初始值。
-XX:MaxNewSize=size 表示新生代最大可占用的空间。
-XX:MaxHeapFreeRatio=70 指定JVM在堆空间的使用率大于70时进行堆空间的扩张,在-Xms==-Xmx的情况下无效。
-XX:MinHeapFreeRatio=40 指定JVM在堆空间的使用率小于40的时候进行堆空间的紧缩,同样,在-Xms==-Xmx的情况下无效。
-XX:PermSize=64m 表示持久代占用的空间,初始值。
-XX:MaxPermSize=64m 表示持久代可占用的最大空间。
-XX:SurvivorRatio=n 设置新生代中,Eden区和Survivor区之间的比例,假如取值为4,由于默认情况下存在两个Survivor区,因此Eden区占用的内存为新生代全部内存的2/3。
-XX:TargetSurvivorRatio=50
GC日志
-Xloggc:<filename> 指定JVM输出GC日志的文件名和路径。
-XX:+UseGCLogFileRotation 是否启用GC日志文件的自动转储。
-XX:NumberOfGClogFiles=1 GC日志文件的绕接数目。
-XX:GCLogFileSize=8K 控制GC日志文件的大小。
-XX:+PrintGC 输出GC日志。
-XX:+PrintGCDetails 输出详细的GC日志。
-XX:+PrintGCTimeStamps 在GC日志中输出时间。
-XX:+PrintTenuringDistribution 在GC日志中输出各代的内存占用情况。
-XX:PrintHeapAtGC GC日志中输出堆的分布情况。
其它
-XX:-DisableExplicitGC 将System.gc()方法的实现替换为空操作,JVM将按照自身的算法判定何时执行GC。
-XX:+ExplicitGCInvokesConcurrent 配合CMS回收器使用,改变System.gc()方法的行为,当代码中显式调用System.gc()方法时,将转换为通知启动CMS收集器工作。
-XX:+UseGCOverheadLimit 在抛出OOM之前限制jvm耗费在GC上的时间比例。启用这个参数可能会出现异常java.lang.OutOfMemoryError: GC overhead limit exceeded,官方的解释是”if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown.“,遇到类似问题,可以采取的规避手段是禁用这个选项,但治本的方法还是检查代码,消除代码中存在的问题代码。
-XX:+UseTLAB 启用线程本地的内存分配器,提高分配效率。
-XX:+HeapDumpOnOutOfMemoryError OOM异常抛出时,JVM将内存中的对象数据导出保存到硬盘上。
-XX:HeapDumpPath=./java_pid<pid>.hprof 显式指定堆内存快照的存储文件路径,默认的路径是在程序的启动目录下。
-XX:ErrorFile=./hs_err_pid<pid>.log 显式指定JVM崩溃时生成的错误日志文件的位置,默认的路径是在程序的启动目录下。
-XX:ParallelGCThreads=n 手工指定并行收集器使用的线程数目。