簡體   English   中英

垃圾收集和線程

[英]Garbage Collection and Threads

AFAIK當GC正在執行其操作時,VM會阻止所有正在運行的線程 - 或者至少在壓縮堆時。 這是CLR和JVM的現代實現中的情況(截至2010年1月的生產版本) 請不要提供有關GC的基本鏈接,因為我了解基本的工作原理。

我假設全局鎖定就是這種情況,因為當壓縮發生時,引用在移動期間可能是無效的,並且最簡單的方法就是鎖定整個堆(即,通過阻塞所有線程來間接)。 我可以想象更強大的機制,但KISS經常占上風。

如果我不正確,我的問題將通過對用於最小化阻塞的策略的簡單解釋來回答。 如果我的假設是正確的,請提供以下兩個問題的一些見解:

  1. 如果這確實是這種行為,那么像JBOSS和Glassfish這樣的重量級企業引擎如何保持一致的高TPS率? 我在JBOSS上做了一些谷歌搜索,我期待在APACHE上找到適合網絡處理的內存分配器。

  2. 面對NUMA式架構(可能在不久的將來),這聽起來像是一場災難,除非進程受到線程和內存分配的CPU限制。

答案是這取決於所使用的垃圾收集算法。 在某些情況下,您在GC期間停止所有線程是正確的。 在其他情況下,在正常線程運行時垃圾收集繼續進行是不正確的。 要了解GC如何實現這一目標,您需要詳細了解垃圾收集器的理論和術語,並結合對特定收集器的理解。 簡單的解釋根本不適合。

哦,是的,值得指出的是,許多現代收藏家本身沒有壓實階段。 相反,它們通過將活動對象復制到新的“空間”並在完成時將舊“空間”歸零來工作。

如果我不正確,我的問題將通過對用於最小化阻塞的策略的簡單解釋來回答。

如果您真的想了解垃圾收集器的工作原理,我建議:

...並注意找到生產垃圾收集器內部的准確,詳細的公開描述並不容易。 (雖然在Hotspot GC的情況下,您可以查看源代碼......)

編輯:回應OP的評論......

“看起來就像我想的那樣 - 沒有繞過”阻止世界“的一部分。”

這取決於。 對於Java 6 Concurrent Collector ,在標記根(包括堆棧)期間有兩個暫停,然后標記/復制其他對象並行進行。 對於其他類型的並發收集器,在收集器運行時使用讀取或寫入障礙來捕獲收集器和應用程序線程否則會相互干擾的情況。 我現在沒有這里的[瓊斯]副本,但我還記得有可能使“停止世界”的間隔可以忽略不計......代價是更昂貴的指針操作和/或不收集所有垃圾。

你是正確的,垃圾收集器將必須暫停所有應用程序線程。 使用並發收集器可以通過sun JVM減少此暫停時間,該收集器可以在不停止應用程序的情況下執行某些工作,但它必須暫停應用程序線程。

請參見http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gchttp://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms有關sun JVM如何管理最新JVM中的垃圾收集的詳細信息。

對於Web應用程序,我認為這不是問題。 由於用戶請求應在<1s的少量時間內完成,因此分配給服務請求的任何臨時對象都不應退出年輕代(如果大小合適),以便非常有效地清理它們。 具有較長生命周期的其他數據(例如用戶會話)將更長時間地停留並且可能影響花費在主要GC事件上的時間。

在高TPS應用程序中,常見的策略是使用會話親緣性和負載平衡在相同或單獨的硬件上運行應用程序服務器的多個實例。 通過這樣做,每個JVM的單個堆大小保持較小,這減少了執行主要集合時GC的暫停時間。 通常,數據庫成為瓶頸,而不是應用程序或JVM。

您可能在J2EE中找到與Web特定內存分配器概念最接近的是由框架和應用程序服務器執行的對象/實例池。 例如,在JBOSS中,您有EJB池和數據庫連接池。 然而,這些對象通常是因為它們的高創建成本而不是垃圾收集開銷而被合並。

我相信IBM已經開展了一些改進多核系統GC性能的研究,其中包括減少或消除“一切停止”問題的工作。

例如,請參閱: 服務器的並行,增量和並發GC(pdf)

或谷歌之類的“並發垃圾收集ibm”

AFAIK當GC正在執行其操作時,VM會阻止所有正在運行的線程 - 或者至少在壓縮堆時。 這是CLR和JVM的現代實現中的情況(截至2010年1月的生產版本)?

Sun的Hotspot JVM和Microsoft的CLR都有並發的GC,它們只在短期內停止世界(獲得所有實時數據可以訪問的全局根的自我一致快照),而不是整個收集周期。 我不確定他們的壓實實現,但這種情況非常罕見。

如果這確實是這種行為,那么像JBOSS和Glassfish這樣的重量級企業引擎如何保持一致的高TPS率?

這些引擎的延遲比停止世界的時間長幾個數量級。 此外,延遲被引用為例如第95百分位,這意味着等待時間僅在95%的時間內低於引用的時間跨度。 所以壓縮不太可能影響引用的延遲。

Java提供了許多GC算法,並非所有這些算法都阻止所有正在運行的線程。 例如,您可以使用-XX:+ UseConcMarkSweepGC,它與應用程序同時運行(用於收集終身代)。

Java的當前最先進的垃圾收集仍然偶爾會“停止世界”暫停。 在Java 6u14上引入的G1 GC可以同時完成大部分工作,但是,當內存非常低時,它需要壓縮堆,然后它必須確保沒有人混淆堆下面的堆。 這要求不允許任何其他事情繼續進行。 要了解有關G1 GC的更多信息,請查看Sun演示文稿

暫無
暫無

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

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