jvm剖析到性能优化

一.文章介绍

       首先带我们先来了解下JVM的内存结构:

 

  1. Metaspance =  Class、Package、Method、Field、字节码、常量池、符号引用等等。
  2. CCS = 32位指针的Class(压缩类空间)
  3. CodeCache = JIT编译后的本地代码、JNI使用的C代码

二JNI.基于JDK命令行工具的监控

   1.JVM的参数类型 

             1.标准参数:功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数

             2.X参数:非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索

                               -Xint:解释执行
                               -Xcomp :第一次使用就编译成本地代码
                               -Xmixed :混合模式,JVM自己来决定是否编译成本地代码

             3.XX参数:非标准 很长一段时间不会列出来 用于JVM开发的debug和调优

                                boolean : -XX:+UseConcMarkSweepGC  :启用CMS垃圾收集器
                                                     -XX:+UseG1GC  :启用G1 垃圾收集器
                                非boolean类型 : -XX:MaxGCPauseMillis=500   //young区GC的回收的时间
                                                                 -XX:GCTimeRatio=19        //吞吐量 也就是垃圾回收时间和非垃圾回收时间的比例   
                                注意:-Xms 等价于 -XX:InitialHeapSize       //jvm初始堆内存  1/64
                                            -Xmx 等价于 -XX:MaxHeapSize           //jvm最大堆内存  1/4
                                             -xss 等价于 -XX:TreadStackSize        //堆栈的大小

   2.查看JVM运行时参数

          -XX:+PrintFlagsInitial             //查看初始值
         -XX:+PrintFlagsFinal               //查看最终值
         -XX:+UnlockExperimentslVMOptions   //解锁实验参数
                  jps:撞门查看java进程
                  jinfo:查看正在运行jvm参数
                             例如:jinfo -flag MaxHeapSize pid
                                         jinfo -flag UseG1GC pid   
                                         jinfo -flag UseConcMarkSweepGC pid
                                         jinfo -flag UseParallelGC

   3.jstat查看JVM统计信息

               option:-class,-compiler,-gc,-printcompilation

                              -class: jstat -class 23029 1000 10

                              -gc: jstat -gc 23029

                              -gc输出的结果:
                                                        S0C、S1C、SOU、S1U:S0和S1的总量与使用量
                                                        EC、EU:Eden区总量与使用量
                                                        OC、OU:Old区总量与使用量
                                                        MC、MU:Metaspace区总量与使用量
                                                        CCSC、CCSU:压缩类空间总量与使用量
                                                        YGC、YGCT:YoungGC的次数与时间
                                                        FGC、FGCT:FullGC的次数与时间
                                                        GCT:总的GC时间
                           
                               -compiler、-printcompilation:jstat -compiler 23029

   4.演示内存溢出

5.如何导出内存映像文件

          1.内存溢出自动导出(不建议使用)
                 -XX:+HeapDumpOnOutOfMemoryError
                  -XX:HeapDumpPath=./

           2.使用jmap命令手动导出
                  jmap -dump:format=b,file=heap.hprof XXX

6.MAT分析内存溢出

          

 

7.jstack与线程的状态

jstack  XXXX

top XXX -p  -H

 

      线程状态图:

      java线程状态:

            NEW 、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

 

https://mp.weixin.qq.com/s/GsxeFM7QWuR--Kbpb7At2w

 

8.jstack实战死循环与死锁

 

 

三.基于JVisualVM的可视化监控

         1.监控本地java进程

https://visualvm.github.io/pluginscenters.html 

https://visualvm.github.io/documentation.html

         2.监控远程的java进程

JAVA_OPTS="$JAVA_OPTS
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.net.preferIPv4Stack=true
-Djava.rmi.server.hostname=10.110.3.62"

 

四.基于Btrace的监控调试

五.Tomcat性能监控与调优

六.JVM层GC调优

JVM层GC调优

程序计数器PC Register:JVM支持多线程同时执行,每一个线程都有自己的PC Register,线程正在执行的方法叫做当前方法,如果是java代码,
                     PC Register里面存放的就是当前正在执行的指令的地址,如果是C代码,则为空。
虚拟机栈JVM Stacks: Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,它的生命周期与线程相同。
                虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于储存局部变量表、操作数栈、动态链接
                方法出口等详细,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。(线程堆栈)
堆Heap:Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域
       的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。
方法区Method Area:方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
                  虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来。
常量池Run-Time Constant Pool:运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,
                             用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
本地方法栈Native Method Stacks:本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,
                              而本地方法栈则为虚拟机使用的Native方法服务。


常用参数:
        -Xms  -Xmx
        -XX:NewSize -XX:MaxNewSize
        -XX:NewRation -XX:SurvivorRatio

        -XX:MetaspaceSize -XX:MaxMetaspaceSize
        -XX:+UseCompressedClassPointers
        -XX:CompressedClassSpaceSize
        -XX:InitialCodeCacheSize
        -XX:ReservedCodeCacheSize

垃圾回收算法:
           引用计数

           思想:枚举根节点,做可达性分析。
           根节点:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量应用、本地方法栈的变量等等。

           标记清除:
           算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有。
           缺点:1、效率不高:标记和清除两个过程的效率都不高。
                2、产生碎片:碎片太多会导致提前GC。
           复制:
           它将可用内存按照容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把
           已经使用过的内存空间一次性清理掉。
           优缺点:实现简单,运行高效,但是空间利用率低。
           
           标记整理:
           标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
           优缺点:没有了内存碎片,但是整理内存比较耗时。


           JVM的垃圾回收算法:分带垃圾回收
           Young区用复制算法
           Old区用标记清除或者标记整理

           对象分配:
           对象优先在Eden区分配
           大对象直接进入老年代:-XX:PretenureSizeThreshold

垃圾收集器:
         串行收集器Serial:Serial、Serial Old
         并行收集器Parallel:Parallel Scavenge、Parallel Old,(吞吐量优先的收集器)
         并发收集器Concurrent:CMS、G1,(停顿时间优先的收集器)


         并行VS并发:
         并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。适合科学计算、后台处理等弱交互场景。
         并发:指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),垃圾收集线程在执行的时候
              不会停顿用户程序的执行。适合对响应时间有需求的场景,比如Web。
         
         停顿时间VS吞吐量
            停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。 -XX:MaxGCPauseMillis
            吞吐量:花在垃圾收集的时间和花在应用时间的占比。 -XX:GCTimeRatio=?,垃圾收集时间占:1/1+?
         
         串行收集器:
            -XX:+UseSerialGC -XX:+UseSerialOldGC
         并行收集器:
            吞吐量优先
            -XX:UseParallelGC -XX:+UseParallelOldGC
            Server模式下的默认收集器
         并发收集器:
         响应时间优先
         CMS:-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
         G1: -XX:+UseG1GC

         垃圾收集器搭配
         配图


         如何选择立即收集器
            1.优先调整堆的大小让服务器自己来选择。
            2.如果内存小于100M,使用串行收集器。
            3.如果是单核,并且没有停顿时间的要求,串行或者JVM自己选。
            4.如果允许停顿时间超过1秒,选择并行或者JVM自己选。
            5.如果响应时间最重要,并且不能超过1秒,使用并发收集器。
         
         收集器详解:
         Parallel Collector
            -XX:+UseParallelGC手动开启,Server默认开启
            -XX:ParallelGCThreads=<N> 多少个GC线程    CPU>8 N=5/8  CPU<8 N=CPU
         Parallel Collector Ergonomics
            -XX:MaxGCPauseMillis=<N>
            -XX:GCTimeRatio=<N>
            -Xms<N>
         动态内存调整
            -XX:YoungGenertionSizeIncrement=<Y>
            -XX:TenuredGenerationSizeIncrement=<T>
            -XX:AdaptiveSizeDecrementScaleFactor=<D>

         CMS Collector
            特点:1.并发收集器
                 2.低停顿 低延迟
                 3.老年代收集器
         CMS垃圾收集过程
            1.CMS initial mark:初始标记Root,STW
            2.CMS concurent mark:并发标记
            3.CMS-concurent-preclean:并发预清理
            4.CMS remark:重新标记,STW
            5.CMS concurent sweep:并发清除
            6.CMS-concurent-reset:并发重置
         CMS缺点
            1.CPU敏感
            2.浮动垃圾
            3.空间碎片
         CMS的相关参数
            -XX:ConcGCThreads: 并发的GC线程数
            -XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩
            -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次
            -XX:CMSInitiatingOccupancyFraction:触发FullGC
            -XX:+UseCMSInitiatingOccupancyOnly:是否动态可调的
            -XX:+CMScavengeBeforeRemark:FullGC之前先做YGC
            -XX:+CMSClassUnloadingEnabled:启动回收Perm区
         iCMS
             1.适用于单核或者双核

         
         G1 Collector
            简介:
                The first focus of G1 is to provide a solution for users running applications that require large heaps with limited GC latency. This means heap sizes of around 6 GB or larger, and a stable and predictable pause time below 0.5 seconds.
                G1的第一个重点是为运行需要具有有限GC延迟的大堆的应用程序的用户提供解决方案。这意味着堆大小约为6 GB或更大,并且稳定且可预测的暂停时间低于0.5秒
            
            1.Region
              图
            2.SATB:Snapshot-At-The-Beginning,它是通过Root Tracing得到的,GC开始时候存活对象的快照。
            3.RSet:记录了其他Region中的对象引用本Region中对象的关系,属于point-into结构(谁引用了我的对象)

            YoungGC
                1.新对象进入Eden区
                2.存活对象拷贝到Survivor区
                3.存活时间达到年龄阀值时,对象晋升到Old区
            MixedGC
                1.不是FullGC,回收所有的Young和部分Old
                2.global concurrent marking
                       :1) Initial marking phase:标记GC Root,STW
                       :2) Root region scanning phase:标记存活Region
                       :3) Concurrent marking phase:标记存活的对象
                       :4) Remark phase:重新标记,STW
                       :5) Cleanup phase:部分STW
                时机:
                    InitiatingHeapOccupancyPercent:堆占有率达到这个数值则触发global concurrent marking,默认45%
                    G1HeapWastePercent:在global concurent marking结束之后,可以知道区有多少空间要被回收,在每次YGC之后和再次
                                        发生Mixed GC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生Mixed GC。
                MixedGC相关参数
                    1.G1MixedGCLiveThresholdPercent:Old区的region被回收时候的存活对象占比
                    2.G1MixedGCCountTarget:一次global concurent marking之后,最多执行Mixed GC的次数
                    3.G1OldCSetRegionThresholdPercent:一次Mixed GC中能被选入CSet的最多old区的region数量
                    4.-XX:+UseG1GC 开启G1
                    5.-XX:G1HeapRegionSize=n,region的大小,1-32M,2048个
                    6.-XX:MaxGCPauseMillis=200 最大停顿时间
                    7.-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent
                    8.-XX:G1ReservePercent=10 保留防止to spance溢出
                    9.-XX:ParallelGCThreads=n
                    10.-XX:ConcGCThreads=n 并发线程数=1/4*并行

                最佳实践:
                       1.年轻代大小:避免使用-Xmn、-XX:NewRatio等显式设置Young区大小,会覆盖暂停时间目标。
                       2.暂停时间目标:暂停实践不要太严苛,其吞吐量目标是90%的应用程序时间和10%的垃圾回收时间,不免直接影响到吞吐量。
                
                是否需要切换到G1:
                              1.50%以上的堆被存活对象占用
                              2.对象分配和晋升的速度变化非常大
                              3.垃圾回收的时间特别长,超过了1秒

 

七.JVM字节码与Java代码层调优

 

 

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值