1、Java性能調優概述
1.1、Web服務器,響應時間、吞吐量是兩個重要的性能參數。
1.2、程序性能的幾個表現:
-
- 執行速度:程序的反映是否迅速,響應時間是否足夠短
- 內存分配:分配是否合理,是否過多地消耗內存或泄露
- 啟動時間:程序從運行到可以正常處理業務需要花費多長時間
- 負載承受能力:當系統壓力上升時,系統的執行速度、響應時間的上升曲線是否平緩
1.3、木桶原理與性能瓶頸
根據木桶原理,系統的最終性能取決於系統中性能表現最差的組件。
有可能成為系統瓶頸的計算資源:
磁盤I/O:
網絡操作:
CPU:
異常:
數據庫:
鎖競爭:
內存:
1.4、Amdahl定律
加速比=優化前系統耗時/優化后系統耗時
設加速比為Speedup,必須串行化的程序比重為F,CPU處理器數量為N,則有:
為了提高系統的速度,僅增加CPU處理器的數量並不一定能起到有效的作用,需要從根本上修改程序的串行行為,提高系統內可並行化的模塊比重,在此基礎上,合理增加並行處理器數量,才能以最小的投入,得到最大的加速比。
1.5 性能調優的層次
設計調優:軟件開發之前;所有調優手段的最上層,對軟件整體質量有決定性的影響。可以規避某一個組件的性能問題,而非改良該組件的實現。(需要熟悉:常用軟件設計方法、設計模式、基本性能組件、常用優化思想)
代碼調優:開發過程中或開發完成后;從微觀上對性能的調整,是產生最直接影響的優化方法。熟悉相關的API,對算法、數據結構的靈活使用。
JVM調優:開發后期;對JVM的運行原理和基本內存結構有一定了解,然后根據程序特點,設置合理的JVM啟動參數。
數據庫調優:分為3個部分
應用層對SQL語句優化:編程技巧,指定列名避免使用*、使用PreparedStatement代替Statement等
數據庫進行優化:冗余字段、水平切割、索引等
數據庫軟件進行優化:以Oracle為例,合理的共享池、緩存緩沖區或者PGA等
操作系統調優:linux,共享內存段、共享內存最大值、最小值、虛擬內存大小、磁盤的塊大小等;wiindows,虛擬內存等
1.6基本調優策略和手段
優化的一般步驟:首先明確性能目標,指出優化的對象和最終目的。其次,在目標平台對軟件進行測試,通過各種性能監控和統計工具,觀測和確認當前系統是否已經達到相關目標,若已經達到,則不再優化;若未達到,則需要查找當前的性能瓶頸。
注意事項:不能為了優化而優化,需要進行慎重的評估。
2、設計優化
2.1、設計模式
2.1.1 單例模式
頻繁使用的對象,可以省略創建對象所花費的時間。
由於new操作的次數減少,對系統內存的使用頻率也會降低,減輕GC壓力,縮短GC停頓時間。
延遲加載、多線程環境(內部類):
public class StaticSingleton{ private StaticSingleton(){ System.out.println("create"); } private static class SingletonHolder{ private static StaticSingleton instance = new StaticSingleton(); } public static StaticSingleton getInstance(){ return SingletonHolder.instance; } }
反射機制,強行調用單例類的私有構造函數,生成多個單例。
程序的序列化和反序列化可能會破壞單例。
2.1.2 代理模式
原因:安全方面,屏蔽客戶端直接訪問真實對象;提升系統性能,對真實對象封裝,從而達到延遲加載;遠程調用中,處理遠程方法調用的技術細節。
動態代理:使用字節碼動態生成加載技術,在運行時生成加載類。
方式:JDK自帶的動態代理、CGLIB、Javassist或者ASM庫。
2.1.3 享元模式
目的:提高系統性能,復用大對象,節省內存空間和對象創建時間。
核心思想:在一個系統中存在多個相同的對象,那么只需共享一份對象的拷貝,而不必為每一次使用都創建新的對象。
幾個概念:享元工廠、抽象享元、具體享元類、Main
SAAS、租戶
享元模式和對象池:享元對象不可相互替代,對象池中的對象都是等價的。