java性能優化筆記(一)概述

性能參考指標:

  • 執行時間: 程序從開始到結束的執行時間。

  • CPU時間: 函數或者線程佔用的cpu時間。

  • 內存分配: 程序運行期間所佔內存。

  • 磁盤吞吐量: 硬盤I/O使用情況。

  • 網絡吞吐量: 網絡使用情況。

  • 響應時間:用戶行爲做出的響應時間,越短性能越好。

短板原理:

一直木桶能裝多少水取決於桶壁最短的那個木板。 
產生短板的資源有:

  • 磁盤I/O:很多應用大部分瓶頸在硬盤的I/O,硬盤比內存慢很多。如果等待磁盤讀寫完成會浪費大量CPU時間,拖累整個系統。

  • 網絡請求:由於網絡不穩定或擁塞控制等都會降低網絡請求效率,如果等待網絡請求結束或者超時時間設置過長會浪費大量CPU時間,拖累整個系統。

  • CPU:一些運算對CPU直接或者不間斷佔用很大,CPU密集型應用會在CPU上產生瓶頸。

  • 程序異常:對於java應用,異常產生構造異常棧並加以處理是很耗費資源的,高頻率出現異常會拖垮整個系統。

  • 數據庫:關係型數據庫在存盤讀盤操作(即磁盤I/O操作),更新索引、鎖等待和競爭都會產生瓶頸。

  • 鎖競爭:高併發應用線程之間互相鎖的競爭,線程上下文切換都是很大的開銷。

  • 內存:內存使用nand flash讀寫速度很快,但如果應用程序和操作系統把內存佔滿,會導致交換分區的使用,內存數據與硬盤交換分區交換數據會產生(即磁盤I/O)瓶頸。

上述瓶頸基本解決方案:

  • 磁盤I/O:使用NIO、零拷貝、mmap映射等技術,儘量異步讀寫硬盤,使用緩存和緩衝區技術。使用SSD硬盤,使用RAID技術提高寫入性能。

  • 網絡請求:CDN或PCDN加速、緩存、合併請求、壓縮報文,儘量異步網絡請求(消息隊列服務、master-worker等),使用NIO。加大帶寬、升級網卡。

  • CPU:持續優化代碼,利用好多線程或多進程,設計合理架構,拆分業務,減少單機複雜運算,避免複雜運算和業務請求摻雜在一起。

  • 異常:處理好邊界、緩衝區等,尤其需要注意避免出現NullPointException,測試時間大於開發時間減少bug出現機率。

  • 數據庫:優化sql語句,注意執行計劃,使用緩存代替數據庫部分功能,根據情景使用合理的存儲引擎,注意鎖,使用連接池,使用PrepareStatment。

  • 鎖競爭:儘量減少鎖競爭,可以使用無鎖的copy-on-write、重入鎖等技術。

  • 內存:優化代碼,分析內存佔用情況,合理配置gc。增大物理內存。

Amdahl定律:

加速比公式:加速比=優化前耗時/優化後耗時 
Speedup ≤ 1/(F+(1-F)/N) 
- Speedup:加速比 
- F:串行化比重 
- N:CPU數量 
根據Amdahl定律,優化的效果取決於CPU數量以及系統中串行化程序比重,CPU數量越多,串行比越低,優化效果越好。

性能調優層次

  • 設計調優:對整體架構進行梳理,找出短板進行優化,適當使用設計模式和以往經驗。詳細進行系統設計。

  • 代碼調優:熟悉基本API、第三方類庫的原理,選擇最適當和最優秀的算法,精簡實現,面向接口。

  • JVM調優:熟悉jvm內存模型,字節碼等深層技術,使用常用監控工具如:visualVM、Jconsole等。進行壓測,調節gc和堆棧大小。

  • 數據庫調優:對sql語句進行調優,分析執行計劃,對數據庫系統配置調優(緩衝區、共享區、連接池等),對數據庫設計進行調優(冗餘、索引、分庫分表、讀寫分離等)

  • 操作系統調優:調節句柄數、關閉沒用服務和端口、調節共享內存、調節交換分區大小等。

最後需要注意:不要因爲優化而優化!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章