JVM调优知识

1.  基本概念

    1.  数据类型

        1.  基本类型

            byte,short,int,long,char,float,double,Boolean

        2.  引用类型

            类类型,接口类型,数组

    2.  堆与栈

        1.  栈是运行时的单位

        2.  堆是存储的单位

2.  性能监控工具

    1.  jinfo

        显示jvm的信息,启动参数等

        jinfo  pid        

Attaching to process ID 28743, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.212-b10
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.212-b10
sun.boot.library.path = /usr/java/jdk1.8.0_212-amd64/jre/lib/amd64
java.protocol.handler.pkgs = org.springframework.boot.loader
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /home/java
java.vm.specification.name = Java Virtual Machine Specification
PID = 28743
java.runtime.version = 1.8.0_212-b10
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /usr/java/jdk1.8.0_212-amd64/jre/lib/endorsed
line.separator = 

java.io.tmpdir = /tmp
java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
spring.beaninfo.ignore = true
sun.nio.ch.bugLevel = 
java.specification.name = Java Platform API Specification
java.class.version = 52.0
java.net.preferIPv4Stack = true
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 2.6.32-431.el6.x86_64
user.home = /home/java
user.timezone = GMT+8
catalina.useNaming = false
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
catalina.home = /tmp/tomcat.9114291105181748790.8082
user.name = java
java.class.path = /usr/local/tomcat-vendor/zhen-vendor-2.0.0.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = /usr/local/tomcat-vendor/zhen-vendor-2.0.0.jar
java.home = /usr/java/jdk1.8.0_212-amd64/jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_212
java.ext.dirs = /usr/java/jdk1.8.0_212-amd64/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /usr/java/jdk1.8.0_212-amd64/jre/lib/resources.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/rt.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/sunrsasign.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/jsse.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/jce.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/charsets.jar:/usr/java/jdk1.8.0_212-amd64/jre/lib/jfr.jar:/usr/java/jdk1.8.0_212-amd64/jre/classes
java.awt.headless = true
java.vendor = Oracle Corporation
catalina.base = /tmp/tomcat.9114291105181748790.8082
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.cpu.isalist = 

VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=2147483648 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=715653120 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=715653120 -XX:OldSize=1431830528 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Xms2048m -Xmx2048m -Duser.timezone=GMT+8 -Djava.net.preferIPv4Stack=true

    2.  jps

        查看java进程

    3.  jstat

        查看jvm统计信息

        1.  类加载的统计信息

            jstat -class  28743 1000 10  每1000ms查看一次类加载情况,总共看10次

            输出结果:           

            Loaded Bytes Unloaded Bytes Time
            13287 25960.3 121 174.7 6.80

字段名说明
Loaded 类加载器加载的类的数量
Bytes 类加载器加载的类的字节数
Unloaded 类加载器未加载的类的数量
Bytes 类加载器未加载的类的字节数
Time 执行类加载和卸载操作所花费的时间

           

        2.  与编译器有关的统计信息

            jstat -compiler 28743 1000 5

            输出结果:           

            Compiled Failed Invalid Time        FailedType     FailedMethod
                 13715         3         0  46.83                     1     com/mysql/jdbc/AbandonedConnectionCleanupThread run        

字段名说明
Compiled 执行的编译任务数
Failed 编译任务失败的次数
Invalid 无效的编译任务数
Time 执行编译任务所花费的时间
FailedType 上次编译失败的编译类型
FailedMethod 上次编译失败的类名和方法

        3.  与垃圾回收有关的统计信息

            1.  jstat -gc 179767

                堆内存 = 年轻代 + 年老代 + 永久代 + 元数据区

                年轻代 = Eden区 + 两个Survivor区(From和To)

字段名说明
S0C 第一个Survivor的容量(kB)
S1C 第二个Survivor的容量(kB)
S0U 第一个Survivor已使用的容量(kB)
S1U 第二个Survivor已使用的容量(kB)
EC Eden区的容量(kB)
EU Eden区已使用的容量(kB)
OC 老年代的容量(kB)
OU 老年代已使用的容量(kB)
MC 元空间的容量(kB)
MU 元空间已使用的容量(kB)
CCSC 压缩类的容量(kB)
CCSU 压缩类已使用的的容量(kB)
YGC 年轻代垃圾收集的次数
YGCT 年轻代垃圾回收消耗时间
FGC Full 垃圾回收次数
FGCT Full 垃圾回收消耗时间
GCT 垃圾回收消耗总时间

                输出结果                               

 

 

 

    4.  jstack

        

    5.  jmap                                                                  

3.  垃圾回收器

    1.  串行回收器

        1.  特点

            -  它仅仅使用单线程进行垃圾回收
            -  它是独占式的垃圾回收
            -  进行垃圾回收时, Java应用程序中的线程都需要暂停(Stop-The-World)
            -  使用复制算法
            -  适合CPU等硬件不是很好的场合

            -  通常老年代垃圾回收比新生代回收要更长时间, 所以可能会使应用程序停顿较长时间

        2.  参数

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

    2.  并行回收器

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

            设置参数

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

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

            设置参数

1
2
3
4
5
-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的比例, 晋升老年代的对象年龄等参数会被自动调整,以达到堆大小, 吞吐量, 停顿时间之间的平衡点

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

            设置参数

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

 

    3.  CMS回收器

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

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

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

            设置参数

1
2
3
4
5
6
7
8
9
10
11
-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服务器上的应用很有用。
       

    4.  G1回收器

        1.  特点

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

        2.  主要步骤

            -  新生代GC

            -  并发标记周期

            -  混合回收

            -  若需要,会进行FullGC

        3.  设置参数

            -XX:+UseG1GC  打开G1收集器开关,

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

        4.  参数选项    

选项 默认值 描述
-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。

                    

        

 

posted @ 2018-10-11 00:03  奋斗史  阅读(207)  评论(0)    收藏  举报