1、堆內存調優
使用場景:調整JVM的堆內存可以幫助避免內存溢出,提高垃圾回收的效率。
java -jar -Xms4g -Xmx4g heapTest-0.0.1-SNAPSHOT.jar
-Xms 參數用于設置JVM啟動時的初始堆大小。
-Xmx 參數用于設置JVM可以使用的最大堆內存大小。
-Xmn 參數用于設置年輕代大小。
2、垃圾回收器選擇和調優
使用場景:合適的垃圾回收器能夠提高應用的響應速度和吞吐量。
# 使用G1垃圾回收器
java -XX:+UseG1GC -jar your-application.jar
UseG1GC 參數用于啟用G1垃圾回收器,它是適用于大堆內存并且需要低延遲的場景。
3、線程堆棧大小調優
使用場景:合理的線程堆棧大小有助于提高線程創建和管理的效率。
java -Xss1m -jar your-application.jar
-Xss 參數用于設置每個線程的堆棧大小。
線程堆棧大小應根據應用的實際需求調整,避免過大消耗過多內存,或過小導致棧溢出。
4、調整年輕代和老年代的比例
使用場景:調整年輕代和老年代的比例可以根據應用的特性來優化垃圾回收行為,影響整體的垃圾回收效率。
# 設置年輕代和老年代的比例為1:2
java -XX:NewRatio=2 -jar your-application.jar
# 解釋
-XX:NewRatio=2 # 設置老年代與年輕代的比例為2,即老年代是年輕代大小的兩倍
-XX:NewRatio 參數用于設置老年代和年輕代的大小比例。
如果你的應用長時間運行并且主要進行老年代垃圾回收,增大這個比例可能會有幫助。
5、設置Survivor區比例
使用場景:在年輕代中,Eden區和Survivor區的比例會影響對象晉升老年代的速度。根據應用的對象生命周期調整這個比例,可以優化內存管理。
# 設置Eden區和Survivor區的比例
java -XX:SurvivorRatio=8 -jar your-application.jar
# 解釋
-XX:SurvivorRatio=8 # 設置Eden區與一個Survivor區的大小比例為8,即Eden是Survivor的8倍
-XX:SurvivorRatio 參數定義了年輕代中Eden區與Survivor區的大小比例。
適當調整這個比例可以優化對象在年輕代的存活時間,減少老年代的壓力。
6、啟用GC日志和調試
使用場景:啟用GC日志可以幫助你監控垃圾回收過程,并對性能問題進行診斷。
# 啟用GC日志
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -jar your-application.jar
# 解釋
-XX:+PrintGCDetails # 打印詳細的GC日志
-XX:+PrintGCDateStamps # 在GC日志中包含時間戳
-Xloggc:gc.log # 指定GC日志輸出文件
啟用這些GC日志參數可以提供關于垃圾回收的詳細信息,包括每次GC的類型、時間、持續時間以及內存回收情況。
這些信息對于理解應用的內存使用模式和調整GC策略非常有用。
壓測工具 AB
Ab(ApacheBench) 測試工具是 Apache 提供的一款測試工具,具有簡單易上手的特點,在測試 Web 服務時非常實用。 ab 一般都是在 Linux 上用。
安裝非常簡單,只需要在 Linux 系統中輸入 yum -y install httpd-tools 命令,就可以了。
使用 AB 進行壓力測試:
ab -c 10 -n 100000
參數的含義:
-n:總請求次數(最小默認為 1);
-c:并發次數(最小默認為 1 且不能大于總請求次數,例如:10 個請求,10 個并發,實際就是 1 人請求 1 次);
-p:post 參數文檔路徑(-p 和 -T 參數要配合使用);
-T:header 頭內容類型(此處切記是大寫英文字母 T);
統計 GC 的情況:jstat -gc 8404 5000 20 | awk '{print $13,$14,$15,$16,$17}
表示對jvm進程Id為8404的進程,每個5秒統計一次gc信息,統計20次結束
GC 頻率
高頻的 FullGC 會給系統帶來非常大的性能消耗,雖然 MinorGC 相對 FullGC 來說好了許多,但過多的 MinorGC 仍會給系統帶來壓力。
7、設置最大停頓時間目標
使用場景:當應用需要低延遲時,可以設置JVM的最大停頓時間目標,這有助于減少垃圾回收造成的延遲。
# 設置最大停頓時間目標
java -XX:MaxGCPauseMillis=200 -jar your-application.jar
# 解釋
-XX:MaxGCPauseMillis=200 # 設置垃圾回收的最大停頓時間為200毫秒
-XX:MaxGCPauseMillis 參數用于告訴垃圾回收器盡量在指定的時間內完成垃圾回收。
這對于需要低延遲的應用特別有用,如實時交互系統。
9、調整大對象直接進入老年代的閾值
使用場景:對于那些創建了大量大對象的應用,調整這些大對象直接晉升到老年代的閾值,可以減少年輕代垃圾回收的次數。
# 設置大對象直接進入老年代的閾值
java -XX:PretenureSizeThreshold=1048576 -jar your-application.jar
# 解釋
-XX:PretenureSizeThreshold=1048576 # 設置大對象(大于1MB)直接在老年代分配
-XX:PretenureSizeThreshold 參數用于設置一個大小閾值,超過這個大小的對象將直接在老年代分配內存。
這有助于減少大對象在年輕代中的分配和復制,特別是對于那些頻繁創建和銷毀大對象的應用。
10、調整GC日志文件的回滾和大小限制
使用場景:當需要長時間收集GC日志進行分析時,管理日志文件的大小和回滾非常重要,以避免消耗過多磁盤空間。
# 設置GC日志文件的回滾和大小限制
java -Xloggc:gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -jar your-application.jar
# 解釋
-Xloggc:gc.log # 指定GC日志輸出文件
-XX:+UseGCLogFileRotation # 啟用GC日志文件的回滾
-XX:NumberOfGCLogFiles=5 # 保留最近的5個GC日志文件
-XX:GCLogFileSize=10M # 每個GC日志文件的最大大小為10MB
這些參數結合使用可以有效管理GC日志文件的大小和數量,避免單個日志文件過大,同時保留足夠的歷史數據供分析。
12、使用并行垃圾回收器
使用場景:對于需要高吞吐量的應用,如批處理或后臺處理系統,使用并行垃圾回收器可以提高效率。
# 使用并行垃圾回收器
java -XX:+UseParallelGC -XX:ParallelGCThreads=4 -jar your-application.jar
# 解釋
-XX:+UseParallelGC # 啟用并行垃圾回收器
-XX:ParallelGCThreads=4 # 設置垃圾回收時使用的線程數為4
并行垃圾回收器在執行GC時會使用多個線程,這可以在多核處理器上顯著提高垃圾回收的效率。
ParallelGCThreads 參數用于指定執行垃圾回收時并行線程的數量,通常設置為與CPU核心數相同。
結論
JVM調優是一項需要根據應用特性和運行環境細致調整的任務。上述的調優方法和參數只是眾多可能性中的一小部分。成功的JVM調優需要對應用的行為有深刻的理解,以及對JVM工作原理的充分了解。
在實際操作中,建議逐步調整參數,并結合性能監控工具來評估調優效果。記住,隨著應用的發展和JVM技術的進步,調優是一個持續的過程。