文章目录
- JVM —— 启动参数
- IDEA 如何配置
- 4个内存参数
- 查看设置JVM内存信息
- 3个标准启动参数
- 常用的标准参数
- 非标准参数(扩展参数)
- XX的使用
- 启动参数的疑问
- 行为参数
- 关于垃圾收集器
- 串行收集器
- 并行收集器(吞吐量优先)
- 并发收集器(响应时间优先)
- 性能调优参数
- 调试参数
- 其它启动参数
- nohup 让进程在后台运行
JVM —— 启动参数
IDEA 如何配置
脚本内容如下:
-server -Xmx3550m -Xms3550m -Xmn1256m -Xss128k -XX:SurvivorRatio=6 -XX:MaxPermSize=256m -XX:ParallelGCThreads=8 -XX:MaxTenuringThreshold=0 -XX:+UseConcMarkSweepGC
解释这段配置:
- -server
设置为server模式。 - -Xmx
设置最大堆内存为3350m - -Xms
设置JVM初始堆内存为3550M。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
- -Xmn
设置年轻代大小为1256m。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。 - -Xss
设置较小的线程栈以支持创建更多的线程,支持海量访问,并提升系统性能。 - -XX:SurvivorRatio
设置年轻代中Eden区与Survivor区的比值。系统默认是8,根据经验设置为6,则2个Survivor区与1个Eden区的比值为2:6,一个Survivor区占整个年轻代的1/8。
- XX:MaxPermSize
设置持久代最大值为256M。 - -XX:ParallelGCThreads
配置并行收集器的线程数。即同时8个线程一起进行垃圾回收。此值一般配置为与CPU数目相等。
- -XX:MaxTenuringThreshold
设置垃圾最大年龄(在年轻代的存活次数)。如果设置为0的话,则年轻代对象不经过Survivor区直接进入年老代。对于年老代比较多的应用,可以提高效率;如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。根据被海量访问的动态Web应用之特点,其内存要么被缓存起来以减少直接访问DB,要么被快速回收以支持高并发海量请求,因此其内存对象在年轻代存活多次意义不大,可以直接进入年老代,根据实际应用效果,在这里设置此值为0。
- XX:+UseConcMarkSweepGC
设置年老代为并发收集。CMS(ConcMarkSweepGC)收集的目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存,适用于应用中存在比较多的长生命周期对象的情况。
4个内存参数
- -Xmx
Java Heap最大值,默认值为物理内存的1/4
,最佳值应该视物理内存大小及计算机内其它内存开销而定; - -Xms
Java Heap初始值,Server端JVM最好将-Xms和-Xmx设置相同
,开发测试机JVM可以大一些。 - -Xmn
Java Heap Young区大小 - -Xss
每个线程的Stack大小
查看设置JVM内存信息
// 最大可用内存,对应-Xmx
Runtime.getRuntime().maxMemory();
// 当前JVM空闲内存
Runtime.getRuntime().freeMemory()
// 当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()总合
Runtime.getRuntime().totalMemory()
- maxMemory (JVM最大可用内存)
可用过-Xmx设置,默认值为物理内存的1/4,值不能高于计算机物理内存; - freeMemory (JVM当前空闲内存)
因为JVM只有在需要内存时才占用物理内存使用,所以,freeMemory()的值一般情况下都很小,而JVM实际可用内存并不等于freeMemory(),应该等于maxMemonry()-totalMemory()+freeMemory()。
- totalMemory (JVM当前所占用的内存总合)
值相当于当前JVM已使用的内存及freeMemory()的总合,会随着JVMl使用内存的增加而增加;
3个标准启动参数
- 标准参数 “-”
输入的时候要输“-”,JVM实现都必须实现这些参数的功能,并且向后兼容;
例如下面代码段,“-”是必须要有的
:
-server -XX:PermSize=196m -XX:MaxPermSize=196m -Xmn320m -Xms768m -Xmx1024m
- 非标准参数 “-X”
默认JVM实现这些参数的功能,但是并不保证所有JVM实现都满足,且保证向后兼容;
执行“$ java -X”显示下面的信息 - 非Stable参数 “-XX”
此参数不同版本的JVM实现会有所不同,未来可能随时取消,慎用;
常用的标准参数
- -verbose:[class|gc|jni]
启动详细输出,范例如下:
# 输出JVM载入类详细信息,当JVM报告说找不到类或者类冲突时可以用到。
java -verbose:class
# 输出每次GC的相关情况。
java -verbose:gc
# 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。
java -verbose:jni
- -client
设置JVM使用Client模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或开发调试;在32位环境下直接运行Java程序默认启用该模式。 - -server
设置JVM使Server模式,特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境。在具有64位能力的JDK环境下默认启用该模式。
非标准参数(扩展参数)
- -Xms512m
设置初始 Java 堆大小(内存),初始内存设置为512,至少要512M。 - -Xmx512m
设置最大 Java 堆大小(内存)。 - -Xmn200m
设置年轻代大小为200M,整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 - -Xss128k
设置 Java 每个线程堆栈大小。减少这个参数能生成更多的线程,但是,操作系统对一个进程内的线程数是有上限的(取决于系统最大内存)。
- -Xloggc:flie
将 GC 状态记录在文件中 (带时间戳),与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中
,文件的位置最好在本地,以避免网络的潜在问题。
若与verbose命令同时出现在命令行中,则以-Xloggc为准。 - -Xprof
输出 cpu 配置文件数据,跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。
XX的使用
-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了;但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX:PermSize、-XX:MaxPermSize等等;
- -XX:NewSize=1024m
设置年轻代初始值为1024M。 - -XX:MaxNewSize=1024m
设置年轻代最大值为1024M。 - -XX:PermSize=256m
设置持久代初始值为256M。 - -XX:MaxPermSize=256m
设置持久代最大值为256M。 - -XX:NewRatio=4
设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:4。 - -XX:SurvivorRatio=4
设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为2:4,即1个Survivor区占整个年轻代大小的1/6。 - -XX:MaxTenuringThreshold=7
表示一个对象如果在Survivor区(救助空间)移动了7次还没有被垃圾回收就进入年老代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。
启动参数的疑问
- -Xmn、-XX:NewSize / -XX:MaxNewSize、 -XX:NewRatio
三组参数都可以影响年轻代大小
,混合使用情况下,优先级是什么?
- 高优先
-XX:NewSize/-XX:MaxNewSize - 中优先
-Xmn(默认等效 -Xmn=-XX:NewSize=-XX:MaxNewSize=?) - 低优先
-XX:NewRatio
推荐使用-Xmn参数,原因是这个参数简洁,相当于一次设定 NewSize/MaxNewSIze,而且两者相等,适用于生产环境。-Xmn 配合 -Xms/-Xmx,即可将堆内存布局完成。
-Xmn参数是在JDK 1.4 开始支持。
行为参数
- -XX:-DisableExplicitGC
禁止调用System.gc();但jvm的gc仍然有效 - -XX:+MaxFDLimit
最大化文件描述符的数量限制 - -XX:+ScavengeBeforeFullGC
新生代GC优先于Full GC执行 - -XX:+UseGCOverheadLimit
在抛出OOM之前限制jvm耗费在GC上的时间比例 - -XX:-UseConcMarkSweepGC(并发收集器之一)
对老生代采用并发标记交换算法进行GC
- -XX:-UseParallelGC(并行收集器之一)
启用并行GC
- -XX:-UseParallelOldGC
对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用 - -XX:-UseSerialGC(串行收集器)
启用串行GC
- -XX:+UseThreadPriorities
启用本地线程优先级
关于垃圾收集器
即 垃圾回收器
,JVM给出3种选择:串行收集器、并行收集器、并发收集器。
串行收集器
是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿;
- -XX:+UseSerialGC
设置串行收集器
并行收集器(吞吐量优先)
是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行;
- -XX:+UseParallelGC
设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集,而年老代仍使用串行收集。
- -XX:ParallelGCThreads=20
配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收
。此值建议配置与CPU数目相等。 - -XX:+UseParallelOldGC
配置年老代垃圾收集方式为并行收集。JDK6.0开始支持对年老代并行收集。 - -XX:MaxGCPauseMillis=100
设置每次年轻代垃圾回收的最长时间(单位毫秒)
。如果无法满足此时间,JVM会自动调整年轻代大小,以满足此时间。 - -XX:+UseAdaptiveSizePolicy
设置此选项后,并行收集器会自动调整年轻代Eden区大小和Survivor区大小的比例,以达成目标系统规定的最低响应时间或者收集频率等指标。此参数建议在使用并行收集器时,一直打开。
并发收集器(响应时间优先)
是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大;
- -XX:+UseConcMarkSweepGC
即CMS收集,设置年老代为并发收集。
CMS收集是JDK1.4后期版本开始引入的新GC算法。它的主要适合场景是对响应时间的重要性需求大于对吞吐量的需求,能够承受垃圾回收线程和应用线程共享CPU资源,并且应用中存在比较多的长生命周期对象。CMS收集的目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存。 - -XX:+UseParNewGC
设置年轻代为并发收集
。
可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此参数。 - -XX:CMSFullGCsBeforeCompaction=0
由于并发收集器不对内存空间进行压缩和整理,所以运行一段时间并行收集以后会产生内存碎片,内存使用效率降低。此参数设置运行0次Full GC后对内存空间进行压缩和整理,即每次Full GC后立刻开始压缩和整理内存。 - -XX:+UseCMSCompactAtFullCollection
打开内存空间的压缩和整理,在Full GC后执行。可能会影响性能,但可以消除内存碎片。 - -XX:+CMSIncrementalMode
设置为增量收集模式。一般适用于单CPU情况。 - -XX:CMSInitiatingOccupancyFraction=70
表示年老代内存空间使用到70%时就开始执行CMS收集,以确保年老代有足够的空间接纳来自年轻代的对象,避免Full GC的发生。
性能调优参数
- -XX:LargePageSizeInBytes=4m
设置用于Java堆的大页面尺寸 - -XX:MaxHeapFreeRatio=70
GC后java堆中空闲量占的最大比例 - -XX:MaxNewSize=size
新生成对象能占用内存的最大值 - -XX:MaxPermSize=64m
老生代对象能占用内存的最大值 - -XX:MinHeapFreeRatio=40
GC后java堆中空闲量占的最小比例 - -XX:NewRatio=2
新生代内存容量与老生代内存容量的比例 - -XX:NewSize=2.125m
新生代对象生成时占用内存的默认值 - -XX:ReservedCodeCacheSize=32m
保留代码占用的内存容量 - -XX:ThreadStackSize=512
设置线程栈大小,若为0则使用系统默认值 - -XX:+UseLargePages
使用大页面内存
黑体加粗在实际工作中是经常用来调试的
调试参数
- -XX:-CITime
打印消耗在JIT编译的时间 - -XX:ErrorFile=./hs_err_pid.log
保存错误日志或者数据到文件中 - -XX:-ExtendedDTraceProbes
开启solaris特有的dtrace探针 -
-XX:HeapDumpPath=./java_pid<pid>.hprof
指定导出堆信息时的路径或文件名 -
-XX:-HeapDumpOnOutOfMemoryError
当首次遭遇OOM时导出此时堆中相关信息 - -XX:OnOutOfMemoryError=“;”
当首次遭遇OOM时执行自定义命令 - -XX:-PrintClassHistogram
遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同 -
-XX:-PrintConcurrentLocks
遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同 - -XX:-PrintCommandLineFlags
打印在命令行中出现过的标记 - -XX:-PrintCompilation
当一个方法被编译时打印相关信息 - -XX:-PrintGC
每次GC时打印相关信息 - -XX:-PrintGC Details
每次GC时打印详细信息 - -XX:-PrintGCTimeStamps
打印每次GC的时间戳 - -XX:-TraceClassLoading
跟踪类的加载信息 - -XX:-TraceClassLoadingPreorder
跟踪被引用到的所有类的加载信息 - -XX:-TraceClassResolution
跟踪常量池 - -XX:-TraceClassUnloading
跟踪类的卸载信息 - -XX:-TraceLoaderConstraints
跟踪类加载器约束的相关信息
其它启动参数
nohup 让进程在后台运行
nohup,当通过java -jar 启动一个Java进程时,我们手动关闭了SSH会话窗,这个Java进程也会被关闭,我们可以通过在java -jar前面加入nohup指令,令其在后台运行:
例:
nohup java -jar rainbow-app2-1.0.0.jar >app2.out 2>&1 &
这句话当意思:
也将在后台启动一个新的进程。并把 java 程序的所有输出(包括所有标准输出和错误输出)都重定向到 app2.out 文件中。这条命令执行之后,控制台输出启动的后台进程的 pid:
示例脚本:
localhost:target user$ nohup java -jar spring-jvm-1.0-SNAPSHOT.jar > app.out 2>&1 &
[1] 73620
- nobup
让新的进程SSH会话窗关闭也能在后台运行; - rainbow-app2-1.0.0.jar >app2.out
将所有的程序输出都重定向到app2.out文件中; - 2>&1
“2>&1 的意思就是将标准错误重定向到标准输出。这里标准输出和标准错误都重定向到 app.out内;”
- &
显示pid;
然后可以通过 ps -ef | grep java 查询java进程情况。