• JVM常用命令和性能调优建议 [Could not create the Java virtual machine]


    一、查看jvm常用命令
    jinfo:可以输出并修改运行时的java 进程的opts。
    jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。
    jstat:一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。
    jmap:打印出某个java进程(使用pid)内存内的所有'对象'的情况(如:产生那些对象,及其数量)。
    jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。

    需要注意在使用这些工具前,先用JPS命令获取当前的每个JVM进程号,然后选择要查看的JVM

    二、jinfo
    jinfo可以查看设置的jvm的信息

    jinfo -flag MaxHeapSize [pid]  能够查看最大堆内存
    jinfo -flag ThreadStackSize [pid] 
    
    jinfo -flags [pid]
    jinfo -flag UseConcMarkSweepGC [pid]
    jinfo -flag UseG1GC [pid]
    jinfo -flag UseParallelGC [pid]
    

    三、查看jvm运行时的参数

    1)java -XX:+PrintFlagsFinal -version
    得出的结果,如果是
    = 表示默认值
    := 表示被用户或者jvm修改后的值
    
    2)-XX:+UnlockDiagnosticVMOptions 解锁诊断参数
    -XX:+PrintCommandLineFlags 打印命令行参数
    
    3)jps
    jps这个没什么好说的,在linux里面ps是查看进程,jps就是java的ps,查看java进程
    如果执行"jps -l"就能查看整个类名
    

    四、jstat
    这个指令用来查看jvm统计信息,主要分以下三类:

    1)类装载
    jstat -class [pid] 1000 10
    这个指令指的是每1秒(1000就是1000ms)查看一次类的装载信息,一共看十次。后面的1000和10可以不要
    
    2)垃圾收集
    -gc、-gcutil、-gccause、-gcnew、-gcold
    
    3)JIT编译
    jstat -compiler [pid]
    jstat -printcompilation [pid]
    

    五、jmap
    jmap是一个很重要的命令,可以查看jvm内存使用情况。可以分为两点讲解:

    1)导出内存映像文件
    内存溢出自动导出,设置参数既可:
    +XX:HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=./
    不用多说,设置内存溢出自动导出还有导出的路径
    
    使用jmap命令手动导出:
    jmap -dump:format=b,file=heap.hprof [pid]
    其中format=b代表用二进制导出
    
    2)查看内存映像文件:
    在这里http://www.eclipse.org/mat/downloads.php下载内存分析工具,然后把dump文件导入分析就可以了。
    

    六 、jstack
    jstack也是一个很重要的命令,可以查看线程使用情况。这里需要知道现场的几种状态,参考如下:

    - NEW状态: The thread has not yet started.
    - RUNNABLE状态:The thread is executing in the JVM.
    - BLOCKED状态:The thread is blocked waiting for a monitor lock.
    - WAITING状态:The thread is waiting indefinitely for another thread to perform a particular action.
    - TIMED_WAITING状态:The thread is waiting for another thread to perform an action for up to a specified waiting time.
    - TERMINATED状态:The thread has exited.
    
    状态之间是怎么转换的呢?参考如下:
    jvm里面查看线程使用情况的命令"jstack [pid]",将得到的线程情况输入一个叫做stack.txt的文件:
    这个stack.txt文件能够查看到jvm里面某个id的线程是用来做什么的?如果发生了死锁,在最后也会列举出来。
    
    在linux里面怎么知道线程线上执行的情况呢,哪些线程占用了很大的内存呢?
    这时可以用这个命令 "top -p [pid] -H" 就能够看到单个进程里面线程的情况:
    
    通过printf  "%x" [pid]  可以将10精致的pid 转换为16进制,转换成16进制有什么用?
    因为jstack出来的线程是十六进制的,通过刚刚那个值,就能够在jstack出来的文件里面找到使用内存最多的线程是哪一个线程了。
    

    七、jvisualvm
    jvisualvm是一个可视化工具,集成了上面指令的几乎所有功能,但是它更加直观,所以jvisualvm也很重要。它也在jdk目录的bin目录下。监控本地应用很简单,直接打开jvisualvm就能看到有本地的了。下面着重介绍监控远程的:

    1)监控远程tomcat
    修改tomcat的Catalina.sh
    
    JAVA_OPTS='-Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.1.54'   
    
    参数说明:
    第一个参数是端口,不用说;
    第二个参数是不需要ssl验证,链接的时候不勾那个属性
    第三个参数是不需要验证
    第四个参数是这个tomcat应用的地址,注意不是jvisualvm的地址。
    
    2)监控远程java应用:
    nohup java 
    -Dcom.sun.management.jmxremote
    -Djava.rmi.server.hostname=192.168.1.54  
    -Dcom.sun.management.jmxremote.port=12344
    -Dcom.sun.management.jmxremote.ssl=false -
    Dcom.sun.management.jmxremote.authenticate=false
    -Djava.net.preferIPv4Stack=true
    -jar test.jar
    
    命令是一样的,但是一定要记住的是这里的192.168.1.54一定是我们的java的应用地址,而不是jvisual的地址!!
    记得开放端口, 然后把需要的添加的机器192.168.1.54添加到jvisualvm的"远程"标签里面,然后在“远程“标签里面添加端口在ip后面就可以。
    

    这里说一下监控远程可能会有一点坑,原因如下:
    1)首先确保在java应用的机器里面可以使用jvisualvm才可以,也就是在java应用的机器里面调用jvisualvm没有报错(可能只是warning),才可以。
    2)可能是jdk版本的问题。有可能确认了多少遍端口和应用的问题,但是就是连不上,所以就要看看是不是jdk版本的问题(也许不是,所以就在需要监控的java应用程序的机器上先试下jvisualvm)

                                                                    JVM性能优化建议                                                                

    一、JVM堆内存划分

    JDK7及以前的版本:一个对象被创建以后首先被放到Nursery内存中的Eden内 存中,如果存活期超两个Survivor之后就会被转移到长时内存中(Old Generation)中。永久内存中存放着对象的方法、变量等元数据信息。通过如果永久内存不够,就会得到如下错误:Java.lang.OutOfMemoryError: PermGen
    JDK8版本:JDK8中把存放元数据中的永久内存从堆内存中移到了本地内存(native memory)中,这样永久内存就不再占用堆内存,它可以通过自动增长来避免JDK7以及前期版本中常见的永久内存错误(java.lang.OutOfMemoryError: PermGen)。JDK8也提供了一个新的设置Matespace内存大小的参数:

    -XX:MaxMetaspaceSize=128m
    

    需要注意:如果不设置Matespaces内存大小参数,JVM将会根据一定的策略自动增加本地元内存空间。如果你设置的元内存空间过小,你的应用程序可能得到以下错误:java.lang.OutOfMemoryError: Metadata space

    二、JVM参数
    -XX 参数被称为不稳定参数,此类参数的设置很容易引起JVM性能上的差异。

    1)不稳定参数语法规则
    布尔类型

    -XX:+<option> '+'表示启用该选项
    -XX:-<option> '-'表示关闭该选项
    

    数字类型

    -XX:<option>=<number>
    # 可跟随单位,例如:'m'或'M'表示兆字节;'k'或'K'千字节;'g'或'G'千兆字节。32K与32768是相同大小的。
    

    字符串类型

    -XX:<option>=<string>
    # 通常用于指定一个文件、路径或一系列命令列表。例如:-XX:HeapDumpPath=./dump.core

    2)行为选项

    选项 默认值 描述
    -XX:-AllowUserSignalHandlers 限于Linux和Solaris默认关闭 允许为java进程安装信号处理器。
    -XX:AltStackSize=16384 仅适用于Solaris,从5.0中删除 备用信号堆栈大小(以字节为单位)
    -XX:-DisableExplicitGC 默认关闭 禁止在运行期显式地调用 System.gc()。注意:你熟悉的代码里没调用System.gc(),不代表你依赖的框架工具没在使用。
    -XX:+FailOverToOldVerifier Java6新引入选项,默认启用 如果新的Class校验器检查失败,则使用老的校验器。解决兼容性问题。
    关联选项:-XX:+UseSplitVerifier
    -XX:+HandlePromotionFailure Java1.5以前默认关闭,Java1.6后默认启用 新生代收集担保,于年老代预留内存。
    -XX:+MaxFDLimit 限于Solaris,默认启用 设置java进程可用文件描述符为操作系统允许的最大值。
    -XX:PreBlockSpin 默认10 控制多线程自旋锁优化的自旋次数
    前置选项:
    -XX:+UseSpinning
    -XX:-RelaxAccessControlCheck 默认关闭,Java1.6引入 在Class校验器中,放松对访问控制的检查。作用与reflection里的setAccessible类似。
    -XX:+ScavengeBeforeFullGC 默认启用 在Full GC前触发一次Minor GC
    -XX:+UseAltSigs 限于Solaris
    默认启用
    为了防止与其他发送信号的应用程序冲突,允许使用候补信号替代 SIGUSR1和SIGUSR2。
    -XX:+UseBoundThreads 限于Solaris
    默认启用
    绑定所有的用户线程到内核线程。 减少线程进入饥饿状态(得不到任何cpu time)的次数。
    -XX:-UseConcMarkSweepGC 默认关闭,Java1.4引入 启用CMS低停顿垃圾收集器。
    -XX:+UseGCOverheadLimit 默认启用,Java1.6引入 限制GC的运行时间。如果GC耗时过长,就抛OutOfMemoryError。
    -XX:+UseLWPSynchronization 限于solaris, 默认启用, Java1.4引入 使用轻量级进程(内核线程)替换线程同步。
    -XX:-UseParallelGC -server时启用, 其他情况下:默认关闭, Java1.4引入 为新生代使用并行清除,年老代使用单线程Mark-Sweep-Compact的垃圾收集器。
    -XX:-UseParallelOldGC 默认关闭, Java1.5引入 为老年代和新生代都使用并行清除的垃圾收集器。开启此选项将自动开启-XX:+UseParallelGC 选项
    -XX:-UseSerialGC -client时启用, 默认关闭, Java1.5引入 使用串行垃圾收集器。
    -XX:-UseSpinning Java1.4.2和1.5需要手动启用, Java1.6默认已启用 启用多线程自旋锁优化。关联选项:-XX:PreBlockSpin=10
    -XX:+UseTLAB Java1.4.2以前和使用-client选项时:默认关闭, 其余版本默认启用 启用线程本地缓存区(Thread Local)
    -XX:+UseSplitVerifier Java1.5默认关闭, Java1.6默认启用 使用新的Class类型校验器 。关联选项: -XX:+FailOverToOldVerifier
    -XX:+UseThreadPriorities 默认启用 使用本地线程的优先级。
    -XX:+UseVMInterruptibleIO 限于solaris, 默认启用, Java1.6引入 在solaris中,允许运行时中断线程

    3)性能选项

    选项 默认值 描述
    -XX:+AggressiveOpts Java1.5 引入,默认关闭,Java1.6后默认开启 开启编译器性能优化。
    -XX:CompileThreshold=10000 默认值:1000 通过JIT编译器,将方法编译成机器码的触发阀值,可以理解为调用方法的次数,例如调1000次,将方法编译为机器码。 [-client: 1,500]
    -XX:LargePageSizeInBytes=4m 默认值:4m,amd64位:2m 设置堆内存的内存最大值。
    -XX:MaxHeapFreeRatio=70 默认70 GC后,如果发现空闲堆内存占到整个预估上限值的70%,则收缩预估上限值。
    -XX:MaxNewSize=size 1.3.1 Sparc: 32m,1.3.1 x86: 2.5m 新生代占整个堆内存的最大值。从Java1.4开始, MaxNewSize成为 NewRatio的一个函数
    -XX:MaxPermSize=64m Java1.5以后::64 bit VMs会增大预设值的30%,1.4 amd64::96m,1.3.1 -client: 32m,其他默认 64m Perm(俗称方法区)占整个堆内存的最大值。
    -XX:MinHeapFreeRatio=40 默认值:40 GC后,如果发现空闲堆内存占到整个预估上限值的40%,则增大上限值。关联选项:-XX:MaxHeapFreeRatio=70
    -XX:NewRatio=2 Sparc -client: 8,x86 -server: 8 ,x86 -client: 12 -client: 4 (1.3) 8 (1.3.1+) ,x86: 12 ,其他:2 新生代和年老代的堆内存占用比例。 例如2表示新生代占年老代的1/2,占整个堆内存的1/3。
    -XX:NewSize=2m 5.0以后: 64 bit Vms 会增大预设值的30%,x86: 1m,x86, 5.0以后: 640k,其他:2.125m 新生代预估上限的默认值。
    -XX:ReservedCodeCacheSize=32m Solaris 64-bit, amd64, -server x86: 48m ,1.5.0_06之前, Solaris 64-bit ,amd64: 1024m ,其他:32m 设置代码缓存的最大值,编译时用。
    -XX:SurvivorRatio=8 Solaris amd64: 6 ,Sparc in 1.3.1: 25 ,Solaris platforms 5.0以前: 32 ,其他:8 Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9? 因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。
    -XX:TargetSurvivorRatio=50 默认值:50 实际使用的survivor空间大小占比。默认是47%,最高90%。
    -XX:ThreadStackSize=512 Sparc: 512 ,Solaris x86: 320 (5.0以前 256) ,Sparc 64 bit: 1024 Linux amd64: 1024 (5.0 以前 0) ,其他:512. 线程堆栈大小,
    -XX:+UseBiasedLocking Java1.5 update 6后引入,默认关闭。Java1.6默认启用。 启用偏向锁
    -XX:+UseFastAccessorMethods 默认启用 优化原始类型的getter方法性能。
    -XX:-UseISM 默认启用 启用solaris的ISM
    -XX:+UseLargePages Java1.5 update 5后引入,默认关闭,Java1.6默认启用 启用大内存分页。关联选项:-XX:LargePageSizeInBytes=4m
    -XX:+UseMPSS Java1.4.1 之前默认关闭,其他版本默认启用 启用solaris的MPSS,不能与ISM同时使用。
    -XX:+UseStringCache 默认开启 缓存常用字符串。
    -XX:AllocatePrefetchLines=1 默认值:1 在使用JIT生成的预读取指令分配对象后读取的缓存行数。如果上次分配的对象是一个实例则默认值是1,如果是一个数组则是3
    -XX:AllocatePrefetchStyle=1 默认值:1 预读取指令的生成代码风格,0- 无预读取指令生成 ,1-在每次分配后执行预读取命令 ,2-当预读取指令执行后使用TLAB()分配水印指针来找回入口,
    -XX:+UseCompressedStrings Java1.6 update 21引入 其中,对于不需要16位字符的字符串,可以使用byte[] 而非char[]。对于许多应用,这可以节省内存,但速度较慢(5%-10%)
    -XX:+OptimizeStringConcat Java1.6 update 20引入 在可能的情况下优化字符串连接操作。

    4)调试选项

    选项 默认值 描述
    -XX:-CITime 默认启用 打印JIT编译器编译耗时。
    -XX:ErrorFile=./hs_err_pid.log Java1.6引入 如果JVM crashed,将错误日志输出到指定文件路径。
    -XX:-ExtendedDTraceProbes Java6引入,限于solaris,默认关闭 启用dtrace诊断
    -XX:HeapDumpPath=./java_pid.hprof 默认是java进程启动位置 堆内存快照的存储文件路径。
    -XX:-HeapDumpOnOutOfMemoryError 默认关闭 在java.lang.OutOfMemoryError 异常出现时,输出一个dump.core文件,记录当时的堆内存快照(见 -XX:HeapDumpPath 的描述)
    -XX:OnError=”;” Java1.4引入 当java每抛出一个ERROR时,运行指定命令行指令集。指令集是与OS环境相关的,在Linux下多数是.sh脚本,windows下是.bat批处理。
    -XX:OnOutOfMemoryError=”;” Java1.4.2 update 12和Java6时引入 当第一次发生java.lang.OutOfMemoryError 时,运行指定命令行指令集。指令集是与OS环境相关的,在linux下多数是.sh脚本,windows下是.bat批处理。
    -XX:-PrintClassHistogram 默认关闭 在Windows下, 按ctrl-break或Linux下是执行kill -3(发送SIGQUIT信号)时,打印class柱状图。 jmap -histo pid也实现了相同的功能。
    -XX:-PrintConcurrentLocks 默认关闭 在thread dump的同时,打印java.util.concurrent的锁状态。jstack -l pid 也同样实现了同样的功能。
    -XX:-PrintCommandLineFlags Java1.5 引入,默认关闭 Java启动时,往stdout打印当前启用的非稳态jvm options。 例如:-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+DoEscapeAnalysis
    -XX:-PrintCompilation 默认关闭 往stdout打印方法被JIT编译时的信息。
    -XX:-PrintGC 默认关闭 开启GC日志打印。显示结果例如: [Full GC 131115K->7482K(1015808K), 0.1633180 secs] ,该选项可通过com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 动态启用。
    -XX:-PrintGCDetails Java1.4引入,默认关闭 打印GC回收的详细信息。 显示结果例如: [Full GC (System) [Tenured: 0K->2394K(466048K), 0.0624140 secs] 30822K->2394K(518464K), [Perm : 10443K->10443K(16384K)], 0.0625410 secs] [Times: user=0.05 sys=0.01, real=0.06 secs] ,该选项可通过com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 动态启用。
    -XX:-PrintGCTimeStamps 默认关闭 打印GC停顿耗时。 显示结果例如: 2.744: [Full GC (System) 2.744: [Tenured: 0K->2441K(466048K), 0.0598400 secs] 31754K->2441K(518464K), [Perm : 10717K->10717K(16384K)], 0.0599570 secs] [Times: user=0.06 sys=0.00, real=0.06 secs] ,该选项可通过com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 动态启用。
    -XX:-PrintTenuringDistribution 默认关闭 打印对象的存活期限信息。 显示结果例如: [GC Desired survivor size 4653056 bytes, new threshold 32 (max 32) - age 1: 2330640 bytes, 2330640 total - age 2: 9520 bytes, 2340160 total 204009K->21850K(515200K), 0.1563482 secs] ,Age1,2表示在第1和2次GC后存活的对象大小。
    -XX:-TraceClassLoading 默认关闭 打印class装载信息到stdout。记Loaded状态。 例如: [Loaded java.lang.Object from /opt/taobao/install/jdk1.6.0_07/jre/lib/rt.jar]
    -XX:-TraceClassLoadingPreorder 1.4.2引入,默认关闭 按class的引用/依赖顺序打印类装载信息到stdout。不同于 TraceClassLoading,本选项只记 Loading状态。 例如: [Loading java.lang.Object from /home/confsrv/jdk1.6.0_14/jre/lib/rt.jar]
    -XX:-TraceClassResolution 1.4.2引入,默认关闭 打印所有静态类,常量的代码引用位置。用于debug。 例如: RESOLVE java.util.HashMap java.util.HashMapEntryHashMap.java:209<br>说明HashMap类的209行引用了静态类java.util.HashMapEntryHashMap.java:209<br>说明HashMap类的209行引用了静态类java.util.HashMapEntry
    -XX:-TraceClassUnloading 默认关闭 打印class的卸载信息到stdout。记Unloaded状态。
    -XX:-TraceLoaderConstraints Java1.6 引入,默认关闭 打印class的装载策略变化信息到stdout。装载策略变化是实现classloader隔离/名称空间一致性的关键技术。
    -XX:+PerfSaveDataToFile 默认启用 当java进程因java.lang.OutOfMemoryError 异常或crashed 被强制终止后,生成一个堆快照文件。
    -XX:ParallelGCThreads=n 默认值:随JVM运行平台不同而异 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
    -XX:+UseCompressedOops 32位默认关闭,64位默认启动 使用compressed pointers。这个参数默认在64bit的环境下默认启动,但是如果JVM的内存达到32G后,这个参数就会默认为不启动,因为32G内存后,压缩就没有多大必要了,要管理那么大的内存指针也需要很大的宽度了
    -XX:+AlwaysPreTouch 默认关闭 在JVM 初始化时预先对Java堆进行摸底。
    -XX:AllocatePrefetchDistance=n 默认值取决于当前JVM 设置 为对象分配设置预取距离。
    -XX:InlineSmallCode=n 默认值取决于当前JVM 设置 当编译的代码小于指定的值时,内联编译的代码。
    -XX:MaxInlineSize=35 默认值:35 内联方法的最大字节数。
    -XX:FreqInlineSize=n 默认值取决于当前JVM 设置 内联频繁执行的方法的最大字节码大小。
    -XX:LoopUnrollLimit=n 默认值取决于当前JVM 设置 代表节点数目小于给定值时打开循环体。
    -XX:InitialTenuringThreshold=7 默认值:7 设置初始的对象在新生代中最大存活次数。
    -XX:MaxTenuringThreshold=n 默认值:15,最大值:15 设置对象在新生代中最大的存活次数,最大值15,并行回收机制默认为15,CMS默认为4。
    -Xloggc: 默认关闭 输出GC 详细日志信息至指定文件。
    -XX:-UseGCLogFileRotation 默认关闭 开启GC 日志文件切分功能,前置选项 -Xloggc
    -XX:NumberOfGClogFiles=1 必须>=1,默认值:1 设置切分GC 日志文件数量,文件命名格式:.0, .1, …, .n-1
    -XX:GCLogFileSize=8K 必须>=8K,默认值:8K GC日志文件切分大小。

    三、垃圾收集器
    1.  串行回收器
    1.1)新生代串行回收器
    特点
    -  它仅仅使用单线程进行垃圾回收
    -  它是独占式的垃圾回收
    -  进行垃圾回收时, Java应用程序中的线程都需要暂停(Stop-The-World)
    -  使用复制算法
    -  适合CPU等硬件不是很好的场合

    设置参数

    -XX:+UseSerialGC   指定新生使用新生代串行收集器和老年代串行收集器, 当以client模式运行时, 它是默认的垃圾收集器
    

    1.2)老年代串行回收器
    特点
    -  同新生代串行回收器一样, 单线程, 独占式的垃圾回收器
    -  通常老年代垃圾回收比新生代回收要更长时间, 所以可能会使应用程序停顿较长时间

    设置参数

    -XX:+UseSerialGC   新生代, 老年代都使用串行回收器
    -XX:+UseParNewGC   新生代使用ParNew回收器, 老年代使用串行回收器
    -XX:+UseParallelGC 新生代使用ParallelGC回收器, 老年代使用串行回收器
    

    2.  并行回收器
    2.1)新生代ParNew回收器
    特点
    -  将串行回收多线程化
    -  使用复制算法
    -  垃圾回收时, 应用程序仍会暂停, 只不过由于是多线程回收, 在多核CPU上,回收效率会高于串行回收器, 反之在单核CPU, 效率会不如串行回收器

    设置参数

    -XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器
    -XX:+UseConcMarkSweepGC 新生代使用ParNew回收器, 老年代使用CMS回收器
    -XX:ParallelGCThreads=n 指回ParNew回收器工作时的线程数量, cpu核数小时8时, 其值等于cpu数量, 高于8时,可以使用公式(3+((5*CPU_count)/8))
    

    2.2)新生代ParallelGC回收器
    特点
    -  同ParNew回收器一样, 不同的地方在于,它非常关注系统的吞吐量(通过参数控制)
    -  使用复制算法
    -  支持自适应的GC调节策略

    设置参数

    -XX:+UseParallelGC  新生代用ParallelGC回收器, 老年代使用串行回收器
    -XX:+UseParallelOldGC  新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器系统吞吐量的控制:
    -XX:MaxGCPauseMillis=n(单位ms)   设置垃圾回收的最大停顿时间,
    -XX:GCTimeRatio=n(n在0-100之间)  设置吞吐量的大小, 假设值为n, 那系统将花费不超过1/(n+1)的时间用于垃圾回收
    -XX:+UseAdaptiveSizePolicy  打开自适应GC策略, 在这种模式下, 新生代的大小, eden,survivior的比例, 晋升老年代的对象年龄等参数会被自动调整,以达到堆大小, 吞吐量, 停顿时间之间的平衡点
    

    2.3)老年代ParallelOldGC回收器
    特点
    -  同新生代的ParallelGC回收器一样, 是属于老年代的关注吞吐量的多线程并发回收器
    -  使用标记压缩算法

    设置参数

    -XX:+UseParallelOldGC  新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器, 是非常关注系统吞吐量的回收器组合, 适合用于对吞吐量要求较高的系统
    -XX:ParallelGCThreads=n   指回ParNew回收器工作时的线程数量, cpu核数小时8时, 其值等于cpu数量, 高于8时, 可以使用公式(3+((5*CPU_count)/8))
    

    3.  CMS回收器(Concurrent Mark Sweep,并发标记清除)
    3.1)老年代的并发回收器
    特点
    -  是并发回收, 非独占式的回收器, 大部分时候应用程序不会停止运行
    -  针对年老代的回收器
    -  使用并发标记清除算法, 因此回收后会有内存碎片, 可以使参数设置进行内存碎片的压缩整理
    -  与ParallelGC和ParallelOldGC不同, CMS主要关注系统停顿时间

    主要步骤
    -  初始标记
    -  并发标记
    -  预清理
    -  重新标记
    -  并发清理
    -  并发重置

    需要注意:初始标记与重新标记是独占系统资源的,不能与用户线程一起执行,而其它阶段则可以与用户线程一起执行

    设置参数

    -XX:-CMSPrecleaningEnabled  关闭预清理, 不进行预清理, 默认在并发标记后, 会有一个预清理的操作,可减少停顿时间
    -XX:+UseConcMarkSweepGC  老年代使用CMS回收器, 新生代使用ParNew回收器
    -XX:ConcGCThreads=n  设置并发线程数量,
    -XX:ParallelCMSThreads=n  同上, 设置并发线程数量,
    -XX:CMSInitiatingOccupancyFraction=n  指定老年代回收阀值, 即当老年代内存使用率达到这个值时, 会执行一次CMS回收,默认值为68, 设置技巧: (Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100)>=Xmn
    -XX:+UseCMSCompactAtFullCollection  开启内存碎片的整理, 即当CMS垃圾回收完成后, 进行一次内存碎片整理, 要注意内存碎片的整理并不是并发进行的, 因此可能会引起程序停顿
    -XX:CMSFullGCsBeforeCompation=n  用于指定进行多少次CMS回收后, 再进行一次内存压缩
    -XX:+CMSParallelRemarkEnabled  在使用UseParNewGC 的情况下, 尽量减少 mark 的时间
    -XX:+UseCMSInitiatingOccupancyOnly  表示只有达到阀值时才进行CMS回收
    -XX:+CMSConcurrentMTEnabled 当该标志被启用时,并发的CMS阶段将以多线程执行,默认开启
    -XX:+CMSIncrementalMode 在增量模式下,CMS 收集器在并发阶段,不会独占整个周期,而会周期性的暂停,唤醒应用线程。收集器把并发阶段工作,划分为片段,安排在次级(minor) 回收之间运行。这对需要低延迟,运行在少量CPU服务器上的应用很有用。
    

    3.2)Class的回收(永久区的回收)
    设置参数

    -XX:+CMSClassUnloadingEnabled  开启回收Perm区的内存, 默认情况下, 是需要触发一次FullGC
    -XX:CMSInitiatingPermOccupancyFraction=n  当永久区占用率达到这个n值时,启动CMS回收, 需上一个参数开启的情况下使用
    

    4. G1回收器JDK1.7后全新的回收器, 用于取代CMS)
    4.1)概述
    特点
    -  独特的垃圾回收策略, 属于分代垃圾回收器
    -  使用分区算法, 不要求eden, 年轻代或老年代的空间都连续
    -  并行性:回收期间, 可由多个线程同时工作, 有效利用多核cpu资源
    -  并发性:与应用程序可交替执行, 部分工作可以和应用程序同时执行
    -  分代GC::分代收集器, 同时兼顾年轻代和老年代
    -  空间整理:回收过程中, 会进行适当对象移动, 减少空间碎片
    -  可预见性:G1可选取部分区域进行回收, 可以缩小回收范围, 减少全局停顿

    主要步骤
    -  新生代GC
    -  并发标记周期

    初始标记新生代GC(此时是并行, 应用程序会暂停止) –> 根区域扫描 –> 并发标记 –> 重新标记(此时是并行, 应用程序会暂停止) –> 独占清理(此时应用程序会暂停止) –> 并发清理
    

    -  混合回收

    这个阶段即会执行正常的年轻代gc, 也会选取一些被标记的老年代区域进行回收, 同时处理新生代和年老轻
    

    -  若需要,会进行FullGC

    混合GC时发生空间不足
    在新生代GC时, survivor区和老年代无法容纳幸存对象时
    以上两者都会导致一次FullGC产生
    

    设置参数

    -XX:+UseG1GC  打开G1收集器开关,
    -XX:MaxGCPauseMillis=n  指定目标的最大停顿时间,任何一次停顿时间超过这个值, G1就会尝试调整新生代和老年代的比例, 调整堆大小, 调整晋升年龄
    -XX:ParallelGCThreads=n  用于设置并行回收时, GC的工作线程数量
    -XX:InitiatingHeapOccpancyPercent=n  指定整个堆的使用率达到多少时, 执行一次并发标记周期, 默认45, 过大会导致并发标记周期迟迟不能启动, 增加FullGC的可能, 过小会导致GC频繁, 会导致应用程序性能有所下降
    

    4.2)参数选项

    选项 默认值 描述
    -XX:+UseG1GC 默认关闭 使用G1垃圾处理器
    -XX:MaxGCPauseMillis=n 默认值:4294967295 设置并行收集最大暂停时间,这是一个理想目标,JVM将尽最大努力来实现它。
    -XX:InitiatingHeapOccupancyPercent=n 默认值:45 启动一个并发垃圾收集周期所需要达到的整堆占用比例。这个比例是指整个堆的占用比例而不是某一个代(例如G1),如果这个值是0则代表‘持续做GC’。默认值是45
    -XX:NewRatio=n 默认值:2 设置年轻代和年老代的比值。例如:值为3,则表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4。
    -XX:SurvivorRatio=n 默认值:8 年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
    -XX:MaxTenuringThreshold=n 默认值:15 设置垃圾最大存活阀值。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
    -XX:ParallelGCThreads=n 默认值:随JVM运行平台不同而异 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
    -XX:ConcGCThreads=n 默认值:随JVM运行平台不同而异 并行垃圾收集时,使用的线程数。默认值和JVM运行的平台有关。
    -XX:G1ReservePercent=n 默认值:10 设置保留用来做假天花板以减少晋升(新生代对象晋升到老生代)失败可能性的堆数目。
    -XX:G1HeapRegionSize=n 默认值根据堆大小而定 使用G1垃圾回收器,java堆被划分成统一大小的区块。这个选项设置每个区块的大小。最小值是1Mb,最大值是32Mb。

    4.3)其他GC相关的设置
    4.3.1)System.gc()

    1)禁用System.gc()
    -XX:+DisableExplicitGC 禁止程序中调用System.gc(), 加了此参数, 程序若有调用, 返回的空函数调用System.gc()的调用, 会使用FullGC的方式回收整个堆而会忽略CMS或G1等相关回收器
    
    2)System.gc()使用并发回收
    -XX:+ExplicitGCCinvokesConcurrent  使用并发方式处理显示的gc, 即开启后, System.gc()这种显示GC才会并发的回收, (CMS, G1)

    4.3.2)并行GC前额外触发的新生代GC

    1)使用并行回收器 (UseParallelGC或者UseParallelOldGC)时, 会额外先触发一个新生代GC, 目的是尽可能减少停顿时间 
    2)若不需要这种特性, 可以使用以下参数去除 
    -XX:-ScavengeBeforeFullGC  即去除在FullGC之前的那次新生代GC, 原本默认值为true 

    4.3.3)对象何时进入老年代

    1)当对象首次创建时, 会放在新生代的eden区, 若没有GC的介入,会一直在eden区, GC后,是可能进入survivor区或者年老代 
    
    2)当对象年龄达到一定的大小 ,就会离开年轻代, 进入老年代, 对象进入老年代的事件称为晋升, 而对象的年龄是由GC的次数决定的, 
       每一次GC,若对象没有被回收, 则对象的年龄就会加1, 可以使用以下参数来控制新生代对象的最大年龄: 
    -XX:MaxTenuringThreshold=n 假设值为n , 则新生代的对象最多经历n次GC, 就能晋升到老年代, 但这个必不是晋升的必要条件 
    -XX:TargetSurvivorRatio=n  用于设置Survivor区的目标使用率,即当survivor区GC后使用率超过这个值, 就可能会使用较小的年龄作为晋升年龄 
    
    3)除年龄外, 对象体积也会影响对象的晋升的, 若对象体积太大, 新生代无法容纳这个对象, 则这个对象可能就会直接晋升至老年代, 可通过以下参
       数使用对象直接晋升至老年代的阈值, 单位是byte 
    -XX:PretenureSizeThreshold 即对象的大小大于此值, 就会绕过新生代, 直接在老年代分配, 此参数只对串行回收器以及ParNew回收有效, 而对ParallelGC回收器无效

    4.3.4)在TLAB上分配对象(Thread Local Allocation Buffer, 线程本地分配缓存)

    TLAB是一个线程专用的内存分配区域, 虚拟机为线程分配空间, 针对于体积不大的对象, 会优先使用TLAB, 这个可以加速对象的分配, TLAB是默认开启的, 若要关闭可以使用以下参数关闭 
    
    -XX:-UseTLAB  关闭TLAB 
    -XX:+UseTLAB  开启TLAB, 默认也是开启的 
    -XX:+PrintTLAB 观察TALB的使用情况 
    -XX:TLABRefillWasteFraction=n  设置一个比率n, 而refill_waste的值就是(TLAB_SIZE/n), 即TLAB空间较小, 大对象无法分配在TLAB,所以会直接分配到堆上,TLAB较小也很容易装满, 因此当TLAB的空间不够分配一个新对象, 就会考虑废弃当前TLAB空间还是直接分配到堆上, 就会使用此参数进行判断, 小于refill_waste就允许废弃, 而新建TLAB来分配对象,而大于refill_waste就直接在堆上分配, 默认是64 
    -XX:+ResizeTLAB  开启TLAB自动调整大小, 默认是开启的, 若要关闭把+号换成-号即可 
    -XX:TLABSize=n  设置一个TLAB的大小, 前提先关闭TLAB的自动调整

    5.  性能调优工具
    5.1)jps  (Java Virtual Machine Process Status Tool)
    主要用来输出JVM中运行的进程状态信息。语法格式如下:

    jps [options] [hostid]
    
    # hostid语法如下:
    [protocol:][[//]hostname][:port][/servername]
    protocol - 如果protocol及hostname都没有指定,那表示的是与当前环境相关的本地协议,如果指定了hostname却没有指定protocol,那么protocol的默认就是rmi。
    hostname - 服务器的IP或者名称,没有指定则表示本机。
    port - 远程rmi的端口,如果没有指定则默认为1099。
    Servername - 注册到RMI注册中心中的jstatd的名称。
    
    # 如果不指定hostid就默认为当前主机或服务器。
    
    # 命令行参数选项
    -q 忽略输出类名、Jar名和传入main方法的参数
    -m 输出传入main方法的参数
    -l 输出main类或Jar的全限名
    -v 输出传入JVM的参数
    -V 输出通过标记的文件传递给JVM的参数(.hotspotrc文件,或者是通过参数-XX:Flags=<filename>指定的文件)
    -J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。
    

    5.2)stack(Java Stack Trace)
    主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

    jstack [option] pid
    jstack [option] executable core
    jstack [option] [server-id@]remote-hostname-or-ip
    
    # 命令行参数选项说明如下:
    -l 长列表,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
    -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
    -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息
    -h | -help打印帮助信息
    

    jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。

    5.3)jmap(Java Memory Map)
    jmap用来查看堆内存使用状况,一般结合jhat使用。jmap语法格式如下:(如果运行在64位JVM上,可能需要指定-J-d64命令选项参数)

    jmap [option] pid
    jmap [option] executable core
    jmap [option] [server-id@]remote-hostname-or-ip
    
    # 参数说明
    executable 产生core dump的java可执行程序
    core 将被打印信息的core dump文件
    remote-hostname-or-ip 远程debug服务的主机名或ip
    server-id 唯一id,假如一台主机上多个远程debug服务
    pid 需要被打印配相信息的java进程id,可以用jps查问
    
    # 基本参数
    -dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件
    -finalizerinfo 打印正等候回收的对象的信息
    -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况
    -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量
    -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来
    -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效
    -h | -help 打印辅助信息
    -J 传递参数给jmap启动的jvm
    

    5.4)jhat(Java Heap Analysis Tool)
    jhat用于对JAVA heap进行离线分析的工具,它可以对不同虚拟机中导出的heap信息文件进行分析

    # jmap -dump:format=b,file=dumpFileName pid
    jmap -dump:format=b,file=/tmp/dump.dat 21711
    
    jhat -port 9998 /tmp/dump.dat
    # 注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存
    
    # 在浏览器中输入主机地址:9998查看
    

    另外,可以使用Eclipse插件MAT(Memory Analyzer Tool)对dump文件进行分析。

    5.5)jstat(Java Virtual Machine Statistics Monitoring Tool)
    Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:

    类的加载及卸载情况
    -  查看新生代、老生代及持久代的容量及使用情况
    -  查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间
    -  查看新生代中Eden区及Survior区中容量及分配情况等

    语法:

    jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
    
    generalOption - 单个的常用的命令行选项,如-help, -options, 或 -version。
    outputOptions -一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。
    
    statOption 根据jstat统计的维度不同,可以使用如下表中的选项进行不同维度的统计,不同的操作系统支持的选项可能会不一样,可以通过-options选项,查看不同操作系统所支持选项
    
    -h n 用于指定每隔几行就输出列头,如果不指定,默认是只在第一行出现列头。
    -J javaOption 用于将给定的javaOption传给java应用程序加载器,例如,“-J-Xms48m”将把启动内存设置为48M
    -t n 用于在输出内容的第一列显示时间戳,这个时间戳代表的时JVM开始启动到现在的时间
    vmid VM的进程号,即当前运行的java进程号
    interval 间隔时间,单位可以是秒或者毫秒,通过指定s或ms确定,默认单位为毫秒
    count 打印次数,如果缺省则打印无数次
    

    ===统计维度与输出===
    1)class 用于查看类加载情况的统计

    2)compiler 用于查看HotSpot中即时编译器编译情况的统计

    3)gc 用于查看JVM中堆的垃圾收集情况的统计

    4)gccapacity 用于查看新生代、老生代及持久代的存储容量情况

    5)gccause 用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。

    6)gcnew 用于查看新生代垃圾收集的情况

    7)gcnewcapacity 用于查看新生代的存储容量情况

    8)gcold 用于查看老生代及持久代发生GC的情况

    9)gcoldcapacity 用于查看老生代的容量

    10)gcpermcapacity 用于查看持久代的容量

    11)gcutil 用于查看新生代、老生代及持代垃圾收集的情况

    12)printcompilation HotSpot编译方法的统计

    示例

    jstat -gc 1618 250 4
    

    5.6)jvisualvm(Java Virtual Machine Monitoring, Troubleshooting, and Profiling Tool)
    jvisualvm同jconsole都是一个基于图形化界面的、可以查看本地及远程的JAVA GUI监控工具,Jvisualvm同jconsole的使用方式一样,直接在命令行打入Jvisualvm即可启动,不过Jvisualvm相比,界面更美观一些,数据更实时。

    5.7)jconsole
    一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了。

    需要注意:在运行jconsole之前,必须要先设置环境变量DISPLAY,否则会报错误,Linux下设置环境变量如下:
    export DISPLAY=:0.0

    5.8)jprofile
    JProfiler是一个需要商业授权的全功能的Java剖析工具(profiler),专用于分析J2SE和J2EE应用程序。

    它把CPU、执行绪和内存的剖析组合在一个强大的应用中。JProfiler可提供许多IDE整合和应用服务器整合用途。JProfiler直觉式的GUI让你可以找到效能瓶颈、抓出内存漏失(memory leaks)、并解决执行绪的问题。它让你得以对heap walker作资源回收器的root analysis,可以轻易找出内存漏失;heap快照(snapshot)模式让未被参照(reference)的对象、稍微被参照的对象、或在终结(finalization)队列的对象都会被移除;整合精灵以便剖析浏览器的Java外挂功能。

    5.9)jca
    Java线程分析工具,专业的线程分析工具兼容sun/oracle JDK dump线程堆,图形化显示线程概括信息,非常容易的定位问题。
    jca是一个类工具 启动方法

    java -jar jca433.jar
    

    5.10)jinfo命令 (Java Configuration Info)
    jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。

    5.11)Jdb命令 (The Java Debugger)
    用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试。

    5.12)Jstatd命令 (Java Statistics Monitoring Daemon)
    jstatd是一个基于RMI(Remove Method Invocation)的服务程序,它用于监控基于HotSpot的JVM中资源的创建及销毁,并且提供了一个远程接口允许远程的监控工具连接到本地的JVM执行命令。

    jstatd是基于RMI的,所以在运行jstatd的服务器上必须存在RMI注册中心,如果没有通过选项”-p port”指定要连接的端口,jstatd会尝试连接RMI注册中心的默认端口。后面会谈到如何连接到一个默认的RMI内部注册中心,如何禁止默认的RMI内部注册中心的创建,以及如何启动一个外部注册中心。
    参数选项

    -nr 如果RMI注册中心没有找到,不会创建一个内部的RMI注册中心。
    -p port RMI注册中心的端口号,默认为1099。
    -n rminame 默认为JStatRemoteHost;如果同一台主机上同时运行了多个jstatd服务,rminame可以用于唯一确定一个jstatd服务;这里需要注意一下,如果开启了这个选项,那么监控客户端远程连接时,必须同时指定hostid及vmid,才可以唯一确定要连接的服务,这个可以参看jps章节中列出远程服务器上Java进程的示例。
    -J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。
    

    安全性
    jstatd服务只能监视具有适当的本地访问权限的JVM,因此jstatd进程与被监控的JVM必须运行在相同的用户权限中。但是有一些特殊的用户权限,如基于UNIX(TM)为系统的root用户,它有权限访问系统中所有JVM的资源,如果jstatd进程运行在这种权限中,那么它可以监视系统中的所有JVM,但是这也带来了额外的安全问题。

    示例

    # 使用内部RMI注册中心(默认端口是1099),启动jstatd
    jstatd -J-Djava.security.policy=jstatd.all.policy
    
    # 使用外部的RMI注册中心,启动jstatd
    rmiregistry&jstatd -J-Djava.security.policy=all.policy
    
    # 外部的RMI注册中心来启动jstatd,此注册中心的端口为2020
    rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020
    
    # 外部的RMI注册中心来启动jstatd,此注册中心的端口为2020,并且绑定到RMI注册中心的名为AlternateJstatdServerName
    rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName
    
    # 禁止内部RMI注册中心的创建
    jstatd -J-Djava.security.policy=all.policy -nr
    
    # 开启RMI日记记录,jstatd运行在开启了日志记录功能的RMI注册中
    jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true
    

    5.13)httpwatch
    网页数据分析工具,对客户端到服务器端的请求,响应数据有效的监控分析。

    6. 生产环境示例
    6.1)Tomcat7
    catalina.sh(只运行一个Tomcat)

    # 8G内存
    JAVA_OPTS="
    -Dfile.encoding=UTF-8
    -server
    -Djava.awt.headless=true
    -Xms6144m
    -Xmx6144m
    -XX:NewSize=1024m
    -XX:MaxNewSize=2048m
    -XX:PermSize=512m
    -XX:MaxPermSize=512m
    -XX:MaxTenuringThreshold=15
    -XX:NewRatio=2
    -XX:+AggressiveOpts
    -XX:+UseBiasedLocking
    -XX:+UseConcMarkSweepGC
    -XX:+UseParNewGC
    -XX:+CMSParallelRemarkEnabled
    -XX:LargePageSizeInBytes=128m
    -XX:+UseFastAccessorMethods
    -XX:+UseCMSInitiatingOccupancyOnly
    -XX:+DisableExplicitGC"
     
    # 16G内存(垃圾回收略)
    JAVA_OPTS="
    -Dfile.encoding=UTF-8
    -server
    -Xms13312m
    -Xmx13312m
    -XX:NewSize=3072m
    -XX:MaxNewSize=4096m
    -XX:PermSize=512m
    -XX:MaxPermSize=512m
    -XX:MaxTenuringThreshold=10
    -XX:NewRatio=2
    -XX:+DisableExplicitGC"
     
    # 32G内存(垃圾回收略)
    JAVA_OPTS="
    -Dfile.encoding=UTF-8
    -server
    -Xms29696m
    -Xmx29696m
    -XX:NewSize=6144m
    -XX:MaxNewSize=9216m
    -XX:PermSize=1024m
    -XX:MaxPermSize=1024m
    -XX:MaxTenuringThreshold=10
    -XX:NewRatio=2
    -XX:+DisableExplicitGC"
    

    6.2)Hadoop
    建议Hadoop进程的GC参数加上如下选项,很多商业版都默认加上了,这对JDK性能提升有很大帮助

    -XX:CMSInitiatingOccupancyFraction=70
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:+UseConcMarkSweepGC
    -XX:-CMSConcurrentMTEnabled
    -XX:+CMSIncrementalMode
    -Djava.net.preferIPv4Stack=true
    

    7. 参考
    JDK8中JVM堆内存划分

    JDK8引进的JVM参数变化记录
    JVM 不稳定参数
    java 8 JVM性能优化
    Java性能优化攻略详解
    Jvm垃圾回收器详细

    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
    jps命令 (Java Virtual Machine Process Status Tool)

                                     Could not create the Java virtual machine                                 

    一般原因如下:
    1)执行程序里的JAVA路径不对造成的!通过"echo $JAVA_HOME"查找出JAVA路径,然后更新程序中的JAVA路径配置即可。
    2)JVM参数不对造成(可能是stack size太小)。修改JVM_OPTIONS配置里的JVM参数值即可。
    3)jdk版本不兼容导致。调整jdk版本(比如jdk版本过低,调整为高版本的jdk)即可。
  • 相关阅读:
    ASP.NET缓存页面
    SQL2005没有服务端开启程序
    Cookie创建以及清除Cookie数组
    http 错误编号大全(转)
    .net 控件库名称
    window.location.hash属性介绍
    CSS半透明滤镜在FIREFOX和IE下面的能够通用的写法
    兼容性问题
    Js获取窗体大小
    springcloud 微服务分布式 flowable 工作流 前后分离vue.js 集成代码生成器 shiro权限
  • 原文地址:https://www.cnblogs.com/kevingrace/p/5616752.html
Copyright © 2020-2023  润新知