當前位置:
首頁 > 知識 > Twitter工程師談JVM調優

Twitter工程師談JVM調優

原文:http://www.slideshare.net/aszegedi/everything-i-ever-learned-about-jvm-performance-tuning-twitter/2-Everything_I_everlearned_about_JVMperformance

一、調優需要關注的幾個方面

內存調優

CPU 使用調優

鎖競爭調優

I/O 調優

二、Twitter 最大的敵人:延遲

導致延遲的幾個原因?

最大影響因素是 GC

其他的有:鎖和線程調度、I/O、演算法數據結構選取不當效率低

三、內存性能調優

(1)內存佔用調優

OutOfMemoryError 異常原因:可能真的數據量太大、可能要數據顯示的太多、可能內存泄露

數據量太大觀察及解決:

查看 GC 日誌, 看 Full GC 前後內存變化, 變化不大說明確實數據量太大

嘗試增加 JVM 的內存使用

考慮這些數據是否真的需要都在內存中嗎? 可以考慮使用: LRU 演算法換入換出等, 弱引用(Soft References)

數據臃腫(Fat data)

當你想做一些奇怪的事情時候回發生數據佔用太大問題,比如:把整個社交圖譜載入到單個 JVM 實例上、載入全部用戶的元數據到單個 JVM 實例上

在 Twitter 這樣大的規模下減少內部數據呈現工作

數據臃腫原因:

(2)填充補全

看個例子

public static class D {

byte d1;

}

public static class E extends D {

byte e1;

}

現在一般是 64-bit 的 JVM,64-bit 的指針會導致 CPU 緩存相比 32-bit 指針減少很多, 所以建議 JVM 參數加入 -XX:+UseCompressedOops 採用指針壓縮將 64-bit 指針壓縮為 32-bit, 但是卻又能使用 64-bit 的內存空間, 達到一舉兩得的作用。另外,建議最大堆小於 30G。

盡量別使用原始類型對象的包裝類

在 Scala 2.7.7 中:Seq[Int] 存 Integer,Array[Int] 存 int, 第一個空間佔用 (24 + 32*length) bytes,第二個空間佔用 (24 + 4*length) bytes。

在 Scala 2.8 中修復了這個問題, 從這我們可以看出:

你不清楚你所使用類庫的性能特徵(比如能用 int 就用 int)

除非在性能分析工具下運行, 否則你可能永遠不知道這個問題

Map 空間佔用(Map footprints)

Guava MapMaker.makeMap() 佔用 2272 bytes

MapMaker.concurrencyLevel(1).makeMap() 佔用 352 bytes

小心使用 Thread Local

典型的問題在線程池 m*n 的資源相關,如 200 線程池使用了 50 個連接,最終有 10000 個連接緩存

考慮使用同步對象或者每次新建一個對象

四、與延遲做鬥爭

性能三角

圖1:內存佔用下降,延遲下降,吞吐量上升

圖2:壓縮(Compactness,即減小內存佔用)率上升,吐量上升,響應速度上升

新生代是如何工作的?

所有新對象分配在 Eden 代,因為新生代 GC 有壓縮,所以內存分配用指針碰撞

當 Eden 滿的時候,進行一次 stop-the-world 的 Minor GC,存活下來的放到 Survivor

經過幾次 Minor GC,還存活下來的對象會被提升(tenured)到老年代

理想化得新生代操作

Eden 代足夠容納超過一組並發的請求和響應對象(這樣沒有 stop-the-world,吞吐量會比較高)

每個 Survivor 空間足夠容納活躍對象和有年齡的對象(減少過早提升到老年代)

提升閾值正好能讓存活時間長的對象早點提升到老年代(給 Survivor 騰出空間)

從新生代開始調優

列印詳細 GC 日誌, 如開啟 JVM 參數:-XX:+PrintGCDetails,-XX:+PrintGCDateStamps,-XX:+PrintHeapAtGC,-XX:+PrintTenuringDistribution 等等...

關注 Survivor 大小,設置合適的 Survivor 大小

關注提升閾值,使長期存活對象快速提升到老年代

(1)-XX:+PrintHeapAtGC

Heap after GC invocations=1 (full 0):

}

(2)-XX:+PrintTenuringDistribution

CMS 調優

CMS 收集器需要更多的內存, 盡量多分配就對了

減少碎片、避免 Full GC

-XX:CMSInitiatingOccupancyFraction=n n一般設置為 75-80(太早啟動降低吞吐量,太晚啟動導致 concurrent mode failed)

響應速度還是太慢?

Minor GC 時有太多存活對象,嘗試減少新生代空間,減少 Survivor 空間,減少晉陞閾值

太多線程。嘗試找到最小的並發層次或者增加更多 JVM 實例

嘗試使用 volatile 而不是 synchronized 減少鎖競爭,嘗試使用 Atomic* 的原子類

用分配 slab 應對 CMS 的碎片問題

Apache 的 Cassandra 內部使用 slab 分配。每個 slab 大小為 2MB,使用 CAS 複製 byte[] 到裡面,使用 Cassandra 前開銷為 30-60 秒每小時, 使用後在3天零十小時開銷 5 秒。

使用分配 slab 的方式有一些局限性:在緩存滿的時候才把緩存內容寫進磁碟,而且對象需要轉化為二進位等問題

智商題:你能在60秒內找出誰放的火嗎?

請返回對話框發送「放火」獲取答案。

小獵推薦

優質IT工作推薦渠道

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序源 的精彩文章:

MVC 動態註冊HttpModule詳解
JVM 診斷調優 CheatSheet
妹子:為什麼我要找個程序員做老公?

TAG:程序源 |

您可能感興趣

DDN收購Intel Lustre系統業務,詳解Lustre系統架構、配置和調優
Instagram的Python性能調優方法介紹
前端學Serverless系列-性能調優
利用Kubernetes和Helm進行高效的超參數調優
3M 反光鞋面!低調優雅的 Air Jordan 1 「Rox Brown」 即將上架
Tomcat 調優測試
Spark調優的關鍵—RDD Cache緩存使用詳解
詳解Linux性能調優之tuned特性
低調優雅!近觀全新配色Nike Premier II足球鞋
keras參數調優
Tomcat 運維常用調優方式
Spark 數據傾斜調優
如何對分散式 NewSQL 資料庫 TiDB 進行性能調優
Kafka參數調優實戰
Python 環境下的自動化機器學習超參數調優
Hadoop虛擬化的性能對比和調優經驗
MySQL 性能調優的10個方法
阿里P8架構師談:資料庫、JVM、緩存、SQL等性能調優方法和原則
通向架構師的道路(第二十四天)之 Oracle 性能調優
Sql性能調優