GSS資安電子報0206期【 Azul Zulu Prime OpenJDK 首度公開 Memory Allocation Pacing 專利技術解析】

訂閱電子報
2023年一月06日(五) AM 09:00
翻譯及整理:叡揚資訊 資訊安全事業處

      世界上所有執行 Java 應用程式的 Java 虛擬機( Java Virtual Machine,JVM ) 之中都有垃圾回收器( Garbage Collector,GC ),用來回收不再需要的記憶體物件。詳細可見「 Java 開發人員都該了解的垃圾回收相關知識 」。這類 GC 是週期性的運作,而執行一個週期需要一定的時間。傳統 Java 採用暫停所有執行緒的策略,待 GC 完成才能繼續執行程式,這能有效回收記憶體,但也導致定期產生應用程式暫停,稱為 Stop-the-world 的現象,且同時,分配到的記憶體越高,暫停的時間便越久,為了避免延遲過久,勢必限制記憶體最大使用量,這也導致 Java 程式可用記憶體不符合現代程式水準。

      Azul Platform Prime 採用的「 C4 垃圾回收器」( C4 Garbage Collector ),能夠與您的 Java 應用程式同時運作,使用 C4 進行垃圾回收不需要暫行任何執行緒,因此不會有所謂的 Stop-the-world 現象。然而,在執行 GC 期間,應用程式會優先執行 GC ,若記憶體分配過快甚至可能在 GC 完成前便耗盡記憶體,進而導致程式暫停。為了避免這種情況,就算是使用 C4 ,還是有可能需要等待 GC 結束才可進行記憶體分配,也還是可能發生程式延遲,因此 Azul 導入了 Allocation Pacing 的專利技術。

      Allocation Pacing(以下簡稱 AP )是 Azul Platform Prime 中的專利技術,用來預防長時間的記憶體分配延遲。在堆積使用量接近 Xmx 時, AP 能夠限制應用程式的分配率,藉此協助降低分配延遲峰值。至於 AP 的運作方式,則是在分配記憶體時,導入許多小型延遲到分配路徑裡,這些路徑與所要求的記憶體分配大小是成比例的。這使得 GC 有更多時間來完成回收,有助於避免耗盡堆積空間而導致長時間停滯,只有在非 ZST 模式( non-ZST mode )才提供 AP 。可用 -XX:-GPGCUseAllocationPacing 停止執行 AP 。

      

「 Allocation Pacing 」是什麼?

      讓我們以下圖來解析「 Allocation Pacing 」。命令列引數「 Xmx 」定義的是 JVM 的記憶體限制(灰線)。在這個配置值為基準之下,會訂一個目標值開始執行 GC ,將已使用的記憶體總量維持在Xmx某個特定比例之下(綠線)。依據記憶體如何獲得分配的比率(攀升的黑線),就能做出一項預測,於正確的時間展開 GC 週期(綠點),而不會超過目標。

image01M

       

      應用程式若有較高的分配率或比預期還大的 live set ,可能會讓 GC 來不及反應,造成堆積使用量超過 GC 目標(綠線)。如果堆積使用量持續增加並達到調節閾值(紅線), AP 就會啟用。 AP 會強制讓最大分配率與 GC 週期長度達到更佳適配。端視剩餘的自由空間而定,經由動態運算,取得強制採用的分配率。因此能使軌跡「平滑化」,趨近 Xmx  臨界值,在執行緒之間,這個減少量與所需的記憶體大小成等比例,進而使調節達到公平且均等的分布,且不會出現停頓。

image02

    

使用 Allocation Pacing 的影響

  • 顯著降低分配延遲的最大時間
  • 執行緒不會瞬間消耗所有 Heap
  • Heap 使用量低於 AP 的閾值時,不會造成損耗

       AP 首要且最主要的影響,則是將長時間的分配延遲分散成許多較小的延遲。如此一來,對應用程式而言,看起來就會比較像是吞吐量( throughput )降低,而非突然發生的延遲。第二個影響,則是 AP 能夠保護應用程式,免受一些個別執行緒的非預期高活動。重新載入一個大型快取子系統,就是一個很好的例子。這類的情況會瞬間提高應用程式的分配率,然後耗盡 Heap 記憶體,而這將導致負責您業務邏輯執行緒的分配延遲。若執行 AP ,分配率就能保持受到控制。 AP 導入的延遲是與分配大小成比例,也就是說,在某個執行緒想獲取更多記憶體分配時,受到的調節程度也越大。因此,重新載入大量快取的執行緒將受到大幅度的調節;至於其他進行較少記憶體分配的執行緒,所受到的影響程度將會較小。

      由於 AP 僅在超過一定程度時啟用,只要應用程式運作時低於調節閾值,其性能就完全不會受到影響。 AP 必須提早開始,才有一些自由空間能夠調動,以便在達到 Xmx 之前,先讓堆積使用量曲線平滑。不過太早開始會帶來風險,可能產生非必要干擾。因為 GC 可能隨時釋出記憶體,而為了執行調節的分配率,記憶體排班程式規劃出公平順暢的分布,進而帶來某些額外的損耗,導致在從事調節時,吞吐量變得較低。

       

以標準檢查程序,說明應用程式調節

     為了模擬分配延遲並且圖解說明 AP 的能力,我們採用了執行 EHCache 的 EHCachePounder 標準檢查程序。我們執行一個 Java agent ,可以週期性的消耗許多 Heap 。這使得分配率和 live set 皆瞬間驟增。 GC 來不及反應,導致 GC 在完成回收記憶體前就耗盡堆積量。因此,標準檢查程序執行緒開始執行分配延遲。

      如果我們啟動 AP , 就能調控分配率,不會讓 GC 趕不上。在堆積使用量越過閾值後,包括標準檢查程序和 Java agent 在內的所有執行緒,皆會依照其分配量,受到等比例的調節。下圖「 GC 與安全點:停滯持續時間」比較中,我們可以看到分配延遲的最大量值(藍線)顯著下降。

image03

     

      這項改善不僅發生在 GC 日誌中,也發生在標準檢查程序指標本身。標準檢查程序以微秒來呈報每迭代的持續時間,一個迭代平均需要 ~0.5 微秒。未受調節時,我們可以看到在 p99.9+ 出現極大的離群值。一旦啟用 AP ,峰值就會下降許多,同時較低的百分位數依然未受影響。在 p90+ 有輕微上升,不過這在預料內,因為 AP 將以許多極小而平滑的延遲來取代長時間的延遲。

image04

       

      下列圖表顯示每 GC 週期發生的分配延遲數量差異。未啟用 AP 時,一旦執行緒發生延遲後,即須等待,直到 GC 釋出某些記憶體(紅線「分配失敗的延遲計數」)為止。反之,若啟用 AP ,就會出現數千個小型延遲(紫線「Allocation Pacing後的延遲計數」)。 GC 日誌分析程式按照分配延遲來源,提供相異的圖例以易於區別。

以下圖表最能解釋 AP 參與其中的效果。

image05

故障排除

偵測AP是否執行

     如同標準檢查程序所示,利用 Azul GC 日誌分析程式 以及您的應用程式日誌檔,您能偵測 AP 是否已經啟用。「 GC與安全點 / GC 與安全點:應用程式執行緒延遲計數」下圖中的「 Allocation Pacing 後的延遲計數」(紫線),顯示 AP 於各 GC 週期中導入的小型延遲數量。

image06

現況的問題是否是 AP 導致?

  • 輕微的 AP 活動本身不會有問題

  • 啟用中的 AP 可能造成吞吐量大幅度降低

  • 如果應用程式指標出現問題,而且與 AP 活動幾乎同時發生,則必須注意

該如何解決問題?

若要避免 AP 執行,最佳方式就是協助 GC 及時完成:

1. 如果 GC 一個接一個執行,意味著還來得及處理問題,只因為 GC 無法接上進度。可嘗試為應用程式增加 Xmx ,給予更多記憶體。

2. 增加目標點與啟動 AP 閾值之間的差距

  • 降低啟動數值:XX:GPGCTargetPeakHeapOccupancyPercent=<value>
  • 提高 AP 閾值(實驗性質的旗標):XX:GPGCPacingTriggerHeapOccupancyPercent=<value>

相關文章

軟體供應鏈必學資安課題,如何拉近開發與資安的距離?

今年 IT 圈最熱門的話題之一,便是資本額達百億元以上的上市櫃公司須在年底前完成設立資安長及資安專責單位。以往資深資安人才本就難尋,如今更是炙手可熱。日前台灣資安主管聯盟的成立大會上,會長金慶柏曾指出,目前全台資安人才缺口超過 4 萬人!既然對外招募不容易,那麼從企業內部培養資安人才、提升人員資安意識便是另一途徑。
2022/06/17

怕被收取高額使用費、資安問題不斷,有沒有好用又有效率的 Java 平台可選擇?

2019 年 Java 使用者開始被收費,導致許多企業組織面臨高額帳單,因此紛紛轉向尋求遵守 OpenJDK 標準的社群,例如 Adopt OpenJDK、甲骨文 OpenJDK 等。

然而,與 Java SDK 相關的安全漏洞層出不窮,再加上即便改用其他 OpenJDK,也會遇上作業系統相容性問題。
2022/06/17

數位政府、開放金融 (open banking)、 數位生態圈 你準備好了嗎?

iThome: https://www.ithome.com.tw/pr/125569 叡揚資訊攜手 Axway 帶領客戶進行數位轉型。 由左至右:叡揚資訊系統事業處 何玉雲處長、Axway 亞太區 ...
2018/08/31