簡體   English   中英

在實時系統中控制Java垃圾收集

[英]Controlling Java garbage collection in real-time system

我們正在用Java運行RT系統。 它通常使用相對較大的堆(100 + GB),並處理來自消息隊列的請求。 必須快速處理每個請求(<100毫秒)才能滿足SLA。

我們遇到了與GC相關的嚴重問題,因為在請求期間(200 + ms),GC通常會導致世界停止收集,從而導致失敗。

我們一位對GC有一定了解的開發人員花了很多時間來調整GC參數並嘗試使用不同的GC。 幾天后,他提出了一些參數化方法,我們戲稱它為“遺傳算法進化”。 它降低了GC暫停時間,但仍遠不能滿足SLA要求。

我正在尋找的解決方案是保護代碼的某些關鍵部分免受GC的侵害 ,在請求完成后,讓GC根據需要進行盡可能多的工作, 然后再接受下一個請求 可以在請求之外偶爾停頓一下,因為我們有幾個工作人員,而垃圾收集工作人員只會暫時不提出請求。

我有一些愚蠢,丑陋的想法,而且很可能行不通,但希望它們能說明問題:

  • 偶爾在接收線程中調用Thread.sleep() ,祈禱GC在此期間做一些工作,
  • 在請求之間調用System.gc()Runtime.gc() ,再次無可救葯地祈求它的幫助,
  • 完全使用https://stackoverflow.com/a/6915221/1137187這樣的駭人模式混淆代碼。

最后要注意的是,我們是一家低成本的初創公司,像Zing®這樣的商業解決方案對我們來說不是一個選擇,我們正在尋找非商業解決方案。

有任何想法嗎? 我們將完全用C ++重寫代碼(我們一開始並不知道GC可能是問題,而不是解決方案),但是代碼庫已經太大了,無法做到這一點。

有任何想法嗎?

使用其他JVM? Azul聲稱能夠處理此類案件。 Redhat和Oracle出於同樣的目標分別向openjdk貢獻了shenandoah和zgc,因此,如果您不想使用商業解決方案,則可以嘗試試驗性構建。

還有其他一些JVM專注於實時應用程序,但是據我了解,它們專注於較小系統上的更嚴格的實時需求,聽起來更像是軟實時需求。

您可以嘗試做的另一件事是通過使用預分配的對象或在適用的情況下使用更緊湊的數據表示形式來顯着減少對象分配(配置應用程序!)。 減少分配壓力,同時保持新的基因組大小不變,這意味着增加每個集合的死亡率,這將加快年輕集合的速度。

選擇硬件以最大化內存帶寬可能也會有所幫助。

在請求之間調用System.gc()或Runtime.gc(),再次無可救葯地祈求它的幫助,

當與-XX:+ExplicitGCInvokesConcurrent結合使用時,這可能會起作用,否則它將使用CMS或G1觸發單線程STW集合(我假設您正在使用其中之一)。 但是這種方法似乎很脆弱,需要大量的調整和監視。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM