性能優化我覺得應該分兩步走,第一步:尋找性能瓶頸,第二步:性能調優;
下面分別進行分析:
通常性能瓶頸的表象是資源消耗過多、外部處理系統的性能不足;或者資源消耗不多,但是程序效應還是很慢;
資源主要消耗在cpu,文件io,網絡io以及內存方面,當某一資源消耗過多會造成系統響應慢;
外部處理系統的性能不足主要是所調用其他系統提供的功能或數據庫的響應速度不夠,外部系統慢可能也是資源消耗過多導致,數據庫響應慢可以對數據庫進行調優;
資源消耗不多但仍然慢主要原因是程序代碼運行效率不高,未充分使用資源或程序結構不合理;
1.1cpu消耗分析
可以通過相關命令比如top,pidstat,找出各個類型消耗cpu的占比,最常見的就是us和sy類型分別代表用戶進程消耗和線程間切換消耗;如果us過高可以找到相關的線程ID然后分析代碼;如果sy過高是不是啟動了過多的線程導致線程切換過多;
1.2文件io消耗
要跟蹤線程的文件IO消耗,可以通過pidstat來查找,可以查到每秒的讀寫kb數;找到讀寫kb數多個線程,然后結合jstack找到相關的java代碼,然后分析;
1.3網絡io消耗
可以通過sar來分析網絡的消耗狀況,但是不能具體到每個線程所消耗的網絡IO,只能對線程dump,查找產生了大量網絡io的線程;
1.4內存消耗
結合top或pidstat,以及jvm的內存分析工具來分析內存消耗;要區分是jvm外的物理內存還是jvmheap區內存;如果是jvm外的物理內存要分析程序中DirectByteBuffer,如果是jvmheap可以通過jvisualvm來分析;
1.5資源消耗不多但仍然慢
主要原因是:鎖競爭激烈,未充分使用硬件資源,數據量增長
2.1jvm調優
主要包括各個代的大小、GC策略等;代大小的設置:避免新生代大小設置過小,或者過大;避免Survivor區過小或過大;合理設置新生代存活周期;GC策略根據吞吐量優先還是延遲優先進行設置策略;
2.2程序調優
1.CPU消耗嚴重解決
us過高主要是執行線程無任何掛起動作,可以進行Thread.sleep操作;sy過高主要是因為創建了過多的線程導致線程上下文切換;
2.文件IO消耗嚴重解決
造成文件IO消耗嚴重的原因主要是多個線程寫大量的數據到同一個文件,導致文件很快變的很大,從而寫入速度越來越慢,并造成各線程激烈競爭爭搶文件鎖,常用的調優方法:異步寫文件,批量讀寫,限流,限制文件大小;
3.網絡IO消耗嚴重解決
主要原因是同時發送或者接受的包太多,解決辦法就是限流;
4.內存消耗嚴重解決
解決:釋放不必要的引用,使用對象緩存池,采用合理的緩存失效策略,合理使用softReference和WeakReference;
2.3資源消耗不多但仍然慢
主要原因是:鎖競爭激烈,未充分使用硬件資源