jvm調優

基於JDK命令行工具的監控php

  JVM的參數類型:html

      標準參數:-help、-server 、-client、 -version、-showversion、-cp、classpathjava

      X參數(非標準參數):-Xint:解釋執行python

                  -Xcomp:第一次使用就編譯本地代碼linux

                  -Xminxed:混合模式,JVM本身來決定是否編譯成本地代碼nginx

      xx參數(非標準參數):Boolean類型:格式:-XX:[+-] <name>表示啓用或禁用name參數git

                        例:-XX:+UseConcMatkSweepGCgithub

                          -XX:+UseG1GCweb

                  非Bollean類型:格式:-XX:<name>=<value>表示name的屬性值是value正則表達式

  運行時JVM參數查看

      -XX:+PrintFlagsInitial  =表示默認值   :=表示JVM修改過的值

      -XX:

      jps  查看java進程

      jinfo  查看運行實參數  

  jstat查看虛擬機統計信息

      類加載信息 -class

      垃圾回收信息 -gc

          s0c、s1c、s0u、s1u:s0和s1的總量與使用量

          ec、eu:Eden區總量與使用量

          oc、ou:old區總量與使用量

          mc、mu:Metaspace區總量和使用量

          ccsc‘ccsu:壓縮類空間總量與使用量

          ygc、ygct:youngGC的次數與時間

          FGC、FGCT:FullGC的次數和時間

          GCT:總的GC時間

          JVM的內存結構:

                

      JIT編譯信息 -compiler

  jmap+MAT實戰內存溢出

      內存溢出自動導出映像文件: -XX:HeapDumpOnOutOfMemoryError

                    -XX:HeapDumpPath=./

      使用jmap命令手動導出:jmap - help 幫助

                 jmap -dump:format=b,file=heap.hrof

      MAT分析:將導出的.hrof文件打開分析各個對象的哥數量和佔用的內存

 

  jstack實戰系循環與死鎖

      命令 jstack pid > 文件名

      java線程的狀態:

        NEW:新new一個線程,尚未啓動

        RUNNABLE:運行狀態,並非就必定執行,可能會等待CPU資源,當得到資源才真正執行

        BLOCKED:等待一個鎖

        WAITING:等待令一個線程來操做

        TIMED_WAITING:等待另外一個線程來操做

        TETMINATED:線程結束 

      狀態轉化過程

         

      

 基於JVisualVM的可視化監控

    監控本地Tomcat

    監控遠程tomcat

    監控普通的JAVA進程

基於Btrace的監控調試

    Btrace能夠動態地向目標應用程序的字節碼注入追蹤代碼

     下載Btrace,新建環境變量BTRACE_HOME,添加Path   %BTRACE_HOME%\bin

     編寫腳本:在idea中編寫,須要引入jar包 btrace-agent.jar、btrace-boot.jar、btrace-client.jar

        

 1 import com.sun.btrace.annotations.*;
 2 import static com.sun.btrace.BTraceUtils.*;
 3 import com.sun.btrace.AnyType;
 4 import com.sun.btrace.BTraceUtils;
 5 
 6 @BTrace
 7 public class TracingScript {
 8     @OnMethod(
 9             clazz="com.fg.jvmstudy.chapter.MemoryController",
10             method="heap",
11             location=@Location(Kind.ENTRY)
12     )
13     public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
14         BTraceUtils.printArray(args);
15         BTraceUtils.println(pcn+","+pmn);
16         BTraceUtils.println();
17     }
18 }

 

      命令行執行腳本:btrace <PID> <trace_script>

              在jvisualvm中運行

    使用詳解

      攔截方法

        

       攔截的時機:

        在入口的地方攔截:默認就是在入口的時候攔截

        在返回時攔截:在AnyType前加@return

         攔截異常

         攔截某一行代碼:在Location加入line參數指定須要攔截的行號

     攔截this,入參,返回

        this:@Self

        入參:能夠用AnyType,也能夠用真實類型,同名的參數用真實類型

        返回值:@Return

        簡單類型:直接獲取

        複雜類型:反射,類名+屬性名,須要指定複雜類型的classpath

 

     注意事項:

        默認只能本地運行

        生產環境下可使用,可是被修改的字節碼不會被還原

tomcat性能監控與調優

     tomcat遠程debug

        jdwp:定義了調試器和被調試的Java虛擬機之間的通訊協議

        配置遠程tomcat

            修改startup.sh

                

            修改catalina.sh

                

       idea:鏈接遠程debug服務並啓動

     tomcat-managet監控

        文檔:docs/manager-howto.html

        步驟:

           conf/tomcat-users.xml添加用戶

             cof/Catalina/localhost/manager.xml配置容許的遠程鏈接

             重啓

     psi-probe監控

        鏈接步驟與tomcat-manage監控同樣

        內容:

          application:應用的統計信息、請求、session、jsp預編譯

          data sources

          Deployment          

          Logs

          Threads

          Clister

          System

          Connectors

          Certificates

          Quick check

       tomcat調優

        內存

        線程

          maxConnections:最大鏈接數

          acceptCount:線程隊列

          maxThreads:工做線程數

          minSpareThreads:最小空閒的工做線程數

        配置

          autoDeploy:是否週期性檢查是否有新的應用進行部署

           enableLookups:在調用request.getRemoteHost()作dns查詢,false時直接返回IP

          reloadable:是否監控WEB-INF下的class和lib,有變化時自動加載

          protocol:鏈接器

          session:能夠禁用session

Nginx性能監控與調優

    ngx_http_stub_status監控鏈接信息

        須要將此模塊編譯,默認已編譯

        添加配置

            localhsot = /nginx_status{

                stub_status on;  打開stub_status

                access_log off;  關閉access_log

                allow 127.0.0.1  容許本機

                deny all;       拒絕全部

            }

        cat 文件  打開文件

    ngxtop監控信息

      安裝python-pip

        yum install epel-release

        yum install python-pip

      安裝ngxtop

        pip install ngxtop

      指定配置文件:ngxtop -c 文件路徑

      查詢狀態是200:ngxtop -c 文件路徑 -i ‘status

      查詢訪問最多IP:ngxtop -c 文件路徑 -g remote_addr

    nginx-rrd圖形化監控

    nginx優化

      配置線程數和併發鏈接數

        worher_processes 4; 受限於cpu

        events{

          worker_connections; 每一個進程打開的最大鏈接數,包含了nginx與客戶端和nginx與upstream之間的鏈接,受限與操做系統

          multi_accept on; 能夠一次創建多少個鏈接

          use epoll;

        }

      啓用長鏈接

        upstream server_pool{

          server lcoalhost:8080 weight=1 max_fail=2

          .......(多個服務)

          keeoalive 300;(三百個長鏈接)

        }

      啓用緩存壓縮

        

      操做系統優化

        sysctl.conf文件

 JVM層GC調優

  JVNM的內存結構

    運行時的數據區(規範):

       程序計數器 PC Register

         JVM支持多線程同時執行,每一個線程都有本身的PC Register,線程正在執行的方法叫作當前方法,若是是java代碼,PC Register裏面存放的就是當前正在執行的指令的地址,若是是C代碼,則爲空

       虛擬機棧JVM Stacks

         Java虛擬機棧是線程私有的,它的生命週期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每一個方法在執行的同時都回船艦一個棧幀,用於存儲局部變量表、操做數棧、動態連接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機中入棧到出棧的過程。

       堆Heap

         Java堆是Java虛擬機所管理的內存中最大的一塊。堆是被全部想成共享的一塊內存區域,在虛擬機啓動時建立。此內存區域的惟一目的就是存放對象實例,幾乎全部的對象實例都在這裏分配內存。

         Java堆能夠處於物理上不連續的內存空間,只要邏輯上市連續的便可。

       方法區Method Area

         方法區與Java堆同樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。雖然Java虛擬機規範把方法區描述爲堆的一個邏輯部分,可是它卻有一個別名叫作Non-Heap,目的是與Java堆區分開來。

       常量池Run-Time Constant Pool

         運行時常量池時方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息時常量池,用於存放編譯期生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池中存放。

      本地方法棧Native Method Stack

      JVM的內存結構:

                

      

      

  垃圾回收算法

    思想:枚舉跟節點,作可達性分析

    根節點:類加載器、Thread、虛擬機棧的本地變量表static成員、常量引用、本地方法棧的變量等等

    標記清除

      算法:

        分爲標記和清除兩個階段,首先標記出全部須要回收的對象,在標記完成後統一回收全部

      缺點:

        效率不高,標記和清除兩個過程效率都不高,產生碎片,碎片太多會致使提早GC

    複製

      算法:

        它將可用內存按容量劃分爲大小相等的兩塊,每次只是用其中的一塊,當者一塊的內存用完了,就將還存活着的對象複製到另外一塊上面,而後再把已使用過的內存空間一次清理掉

      優缺點:

        實現簡單,運行高效,空間利用率低

    標記整理

      算法

        標記過程仍然與標記清除算法同樣,但後續步驟不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,而後直接清理掉端邊界之外的內存

      優缺點

        沒有了內存碎片,可是整理時耗時

    分帶垃圾回收

      young區用複製算法

      Old區用標記清除或者標記整理

      對象優先在Eden區分配

      大對象直接進入老年代:-XX:PretenureSizeThreshold

      長期存活對象進入老年代:

            -XX:MaxTenuringThreshold

            -XX:+PrintTenuringDistribution

            -XX:TargetSurvivorRatio

  垃圾收集器

    串行收集器Serial:Serial、Serial Old

      -XX:+UserSerialGC,-XX:UseSerialOldGC

    並行收集器Parallel:Parallel Scavenge、Parall Old,

      暫停應用程序,開啓多個垃圾收集線程,結束後自動啓用應用程序

      吞吐量優先

      -XX:+UseParallelGC,-XX:+UseParallelOldGC

      Server模式下的默認收集器

      自適應

        -XX:MaxGCPauseMillis=<N>   最大等待時間

        -XX:GCTimeRatio=<N>    吞吐量

        -Xmx<N>          堆大小

        注:不是最優

      動態內存調整

         -XX:YoungGenerationSizelncrement=<Y> Young區增大默認20%

         -XX:TenuredGenerationSizelncrement=<T> Old區增大默認20%

         -XX:AdaptiveSizeDecrementScaleFactor=<D> 減少默認4%

    併發收集器Concurrent:CMS、G1,停頓時間

      響應時間優先

      CMS:-XX:+UseConcMarkSweepGC,-XX:+UseParNewGC

        過程:

          一、CMS initial mark:初始標記Root,STW

          二、CMS concurrent mark:併發標記

          三、CMS-concurrent-preclean:併發預清理

          四、CMS remark:從新標記,STW

          五、CMS concurrent sweep:併發清除

          六、CMS-concurrent-reset:併發重置

        缺點:

          CPU敏感、浮動垃圾、空間碎片

        CMS的相關參數

          -XX:ConcGCThreads:併發的GC線程數

          -XX:+UseCMSCompactAtFullCollection:FullGC後作壓縮

          -XX:+CMSFullGCsBeforeCompaction:多少次FullGC以後作壓縮

          -XX:CMSSlnitiatingOccupancyFraction:觸發FullGC

          -XX:+UseCMSInitiatingOccupancyOnly:是否動態調整

          -XX:+CMSScavengeBeforeRemark:FullGC以前先作YGC

          -XX:+CMSClassUnloadingEnabled:啓用回收Perm區

        iCMS:適用於單核或雙核  

      G1:-XX:+UseG1GC(jdk7之後)

        

    並行(Parallel):指多條垃圾收集線程並行工做,但此時用戶線程仍然處於等待狀態。適合科學計算、後臺處理等弱交互場景

    併發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不必定是並行的,可能會交替執行),垃圾收集線程在執行的時候不會停頓用戶程序的運行。適合對響應的時間有要求的場景,好比WEB

    停頓時間:垃圾收集器作垃圾回收中斷應用執行的時間。

         -XX:maxGCPauseMillis

    吞吐量:花在垃圾收集的時間和花在應用時間的佔比。

         -XX:GCTimeRatio=<n>,垃圾收集時間佔:1/1+n

    垃圾收集器搭配

        

     如何選擇垃圾收集器

       優先調整堆的大小讓服務器本身選擇

       若是內存小於100M,使用串行收集器

       若是是單核,而且沒有停頓時間的要求,串行或者JVM自行選擇

       若是容許停頓時間超過1秒,選擇並行或者JVM本身選

         若是響應時間最重要,而且不能超過1秒,使用並行收集器

 

       

  可視化GC日誌分析工具

   

Java代碼層的調優

  jvm字節碼指令與javap

  i++與++i

    i++:先使用再++

    ++i:先++再使用

    字節碼:

      

  字符串拼接

    String str = "";

    for(int=0;i<10;i++){

      str = str + "A";

    }

    字節碼

      

 

   Try-funlly

    String str = "a";

    try{

      return str;

    }

    finally{

      str = "b"

    }

    

  String Constant Variable 

    

     

 

經常使用代碼優化方法

  儘可能重用對象,不要循環建立對象,

  容器類初始化的時候指定長度

  ArrayList隨機遍歷快,LinkedList添加刪除快

  集合遍歷的時候儘可能減小重複計算

  使用Entry遍歷Map 

  大數組複製用System.arraycopy

  儘可能使用基本類型而不是包裝類型

  不要手動調用System.gc()

  及時消除過時對象的引用,防止內存泄漏

  儘可能使用局部變量,減少變量的做用域

  儘可能使用非同步的容器

  儘可能減少同步代碼塊範圍

  ThreadLocal緩存線程不安全的對象,SimpleDateFormat

  儘可能使用延遲加載

  儘可能減小使用反射,加緩存

  儘可能使用鏈接池、線程池、對象池、緩存

  及時釋放資源

  慎用異常,不要用拋異常來表示正常的業務邏輯

  String操做盡可能少用正則表達式

  日誌輸出注意使用不一樣的級別

  日誌中參數拼接使用佔位符

    

 

 

 

 

 

附錄:

jdk8工具集

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html

Troubleshooting

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/

jps

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

jinfo

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html

jstat

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

jmap:

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

mat:

http://www.eclipse.org/mat/downloads.php

jstack:

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html

java線程的狀態

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html

java線程狀態轉化:

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

死循環致使CPU負載高

https://blog.csdn.net/goldenfish1919/article/details/8755378

正則表達式致使死循環:

https://blog.csdn.net/goldenfish1919/article/details/49123787

 

jvisualVM:

https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/index.html

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

jvisulaVM如何添加插件

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

 

btrace下載

https://github.com/btraceio/btrace

https://github.com/btraceio/btrace/releases/tag/v1.3.11

 

jdwp協議:

https://www.ibm.com/developerworks/cn/java/j-lo-jpda3/

tomcat-manager:

{tomcat}/webapps/docs/manager-howto.html

psi-probe:

https://github.com/psi-probe/psi-probe

tomcat優化相關參數:

${tomcat}/webapps/docs/config/http.html

${tomcat}/webapps/docs/config/host.html

${tomcat}/webapps/docs/config/context.html

${tomcat}/webapps/docs/connectors.html

apr鏈接器:

http://apr.apache.org/

 

nginx官網文檔

http://nginx.org/en/docs/

nginx安裝:

http://nginx.org/en/linux_packages.html

ngx_http_stub_status:

http://nginx.org/en/docs/http/ngx_http_stub_status_module.html

ngxtop:

https://github.com/lebinh/ngxtop

nginx-rdd

http://www.linuxde.net/2012/04/9537.html

 

jvm的運行時數據區

https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

Metaspace

http://ifeve.com/jvm-troubleshooting-guide-4/

壓縮類空間

https://blog.csdn.net/jijijijwwi111/article/details/51564271

CodeCache

https://blog.csdn.net/yandaonan/article/details/50844806

http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/

GC調優指南:

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html

如何選擇垃圾收集器

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html

G1最佳實踐

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

G1 GC的一些關鍵技術

https://zhuanlan.zhihu.com/p/22591838

CMS日誌格式

https://blogs.oracle.com/poonam/understanding-cms-gc-logs

G1日誌格式

https://blogs.oracle.com/poonam/understanding-g1-gc-logs

GC日誌分析工具

http://gceasy.io/   

GCViewer

https://github.com/chewiebug/GCViewer

ZGC:

http://openjdk.java.net/jeps/333

 

java虛擬機規範

https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

java語言規範

https://docs.oracle.com/javase/specs/jls/se8/html/index.html

javap:

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javap.html

字段描述符

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2

方法描述符

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3

字節碼指令:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html

常量池:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4

本地變量表:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.1

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13

操做數棧:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.2

Code屬性:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3

LineNumberTable:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12

constant variable:

https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4

常量表達式

https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28

String.intern

https://blog.csdn.net/goldenfish1919/article/details/80410349

String去重

https://blog.csdn.net/goldenfish1919/article/details/20233263

相關文章
相關標籤/搜索