天天看點

JVM 性能調優

JVM 性能調優
GitHub:https://github.com/wangzhiwubigdata/God-Of-BigData

                   關注公衆号,内推,面試,資源下載下傳,關注更多大資料技術~
                   大資料成神之路~預計更新500+篇文章,已經更新50+篇~ 
           

JVM 性能調優

在高性能硬體上部署程式,目前主要有兩種方式:

  • 通過 64 位 JDK 來使用大記憶體;
  • 使用若幹個 32 位虛拟機建立邏輯叢集來利用硬體資源。

使用64位JDK管理大記憶體

堆記憶體變大後,雖然垃圾收集的頻率減少了,但每次垃圾回收的時間變長。 如果堆記憶體為14 G,那麼每次 Full GC 将長達數十秒。如果 Full GC 頻繁發生,那麼對于一個網站來說是無法忍受的。

對于使用者互動性強、對停頓時間敏感的系統,可以給 Java 虛拟機配置設定超大堆的前提是有把握把應用程式的 Full GC 頻率控制得足夠低,至少要低到不會影響使用者使用。

可能面臨的問題:

  • 記憶體回收導緻的長時間停頓;
  • 現階段,64位 JDK 的性能普遍比 32 位 JDK 低;
  • 需要保證程式足夠穩定,因為這種應用要是産生堆溢出幾乎就無法産生堆轉儲快照(因為要産生超過 10GB 的 Dump 檔案),哪怕産生了快照也幾乎無法進行分析;
  • 相同程式在 64 位 JDK 消耗的記憶體一般比 32 位 JDK 大,這是由于指針膨脹,以及資料類型對齊補白等因素導緻的。

使用32位JVM建立邏輯叢集

在一台實體機器上啟動多個應用伺服器程序,每個伺服器程序配置設定不同端口, 然後在前端搭建一個負載均衡器,以反向代理的方式來配置設定通路請求。

考慮到在一台實體機器上建立邏輯叢集的目的僅僅是為了盡可能利用硬體資源,并不需要關心狀态保留、熱轉移之類的高可用性能需求, 也不需要保證每個虛拟機程序有絕對的均衡負載,是以使用無 Session 複制的親合式叢集是一個不錯的選擇。 我們僅僅需要保障叢集具備親合性,也就是均衡器按一定的規則算法(一般根據 SessionID 配置設定) 将一個固定的使用者請求永遠配置設定到固定的一個叢集節點進行處理即可。

可能遇到的問題:

  • 盡量避免節點競争全局資源,如磁盤競争,各個節點如果同時通路某個磁盤檔案的話,很可能導緻 IO 異常;
  • 很難高效利用資源池,如連接配接池,一般都是在節點建立自己獨立的連接配接池,這樣有可能導緻一些節點池滿了而另外一些節點仍有較多空餘;
  • 各個節點受到 32 位的記憶體限制;
  • 大量使用本地緩存的應用,在邏輯叢集中會造成較大的記憶體浪費,因為每個邏輯節點都有一份緩存,這時候可以考慮把本地緩存改成集中式緩存。

調優案例分析與實戰

場景描述

一個小型系統,使用 32 位 JDK,4G 記憶體,測試期間發現服務端不定時抛出記憶體溢出異常。 加入 -XX:+HeapDumpOnOutOfMemoryError(添加這個參數後,堆記憶體溢出時就會輸出異常日志), 但再次發生記憶體溢出時,沒有生成相關異常日志。

分析

在 32 位 JDK 上,1.6G 配置設定給堆,還有一部分配置設定給 JVM 的其他記憶體,直接記憶體最大也隻能在剩餘的 0.4G 空間中分出一部分, 如果使用了 NIO,JVM 會在 JVM 記憶體之外配置設定記憶體空間,那麼就要小心“直接記憶體”不足時發生記憶體溢出異常了。

直接記憶體的回收過程

上一篇: JVM性能調優
下一篇: Hive優化