基於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