簡體   English   中英

線程局部對象池

[英]Thread-local object pooling

通過Goetz“Java Concurrency in Practice”一書,他提出了一個反對使用對象池(第11.4.7節)的案例 - 主要論點:

1)Java中的分配比C的malloc快2)從池中請求對象的線程需要昂貴的同步

我的問題不在於分配速度慢,而是定期垃圾收集在響應時間中引入了異常值,可以通過減少對象池來消除。

在使用這種方法時,我沒有看到任何問題嗎? 基本上我是跨線程划分對象池...

如果它的線程本地,那么你可以忘記這個:

2)從池中請求對象的線程需要昂貴的同步

作為線程本地,您不必擔心從池本身檢索同步。

在Java 1.4中,對象分配相對昂貴,因此即使是簡單對象的對象池也可以提供幫助。 但是,在Java 5.0中,對象分配得到了顯着改善,但是同步仍有一段路要走,這意味着對象分配比同步更快。 即在許多情況下刪除對象池改進了性能。 在Java 6中,同步已經改進到對象池在簡單情況下可以對性能產生一點差異的程度。

避免使用簡單的對象池是一個好主意,因為它更簡單,不是出於性能原因。

對於更復雜/更大的對象,即使您使用同步,對象池在Java 6中也很有用。 例如,套接字,文件流或數據庫連接。

(太陽)GC掃描實時對象。 假設在典型的Java程序運行時中存在比活動對象更多的死對象。 它標志着活物,並處理其余部分。

如果你緩存很多對象,它們都是實時的。 如果你有幾GB這樣的物體,GC會浪費很多時間徒勞地掃描它們。 長時間的GC暫停會使您的應用程序癱瘓。

緩存一些東西只是為了讓它非垃圾無法幫助GC。

這並不是說緩存是錯誤的。 如果您有15G內存,而您的數據庫是10G,為什么不將所有內容緩存在內存中,因此響應速度很快。 請注意,這是緩存一些本來很慢的東西。

為了防止GC無效地掃描10G緩存,緩存必須在GC的控制之外。 例如,使用“memcached”,它存在於另一個進程中,並具有自己的緩存優化GC。

最新消息是Terracotta的BigMemory,它是一個純Java解決方案,可以做類似的事情。


線程本地池的一個例子是sun的直接ByteBuffer池。 我們打電話的時候

channel.read(byteBuffer)

如果byteBuffer不是“直接”,則必須在引擎蓋下分配“直接”,用於與OS通信數據。 在網絡應用程序中,這樣的分配可能非常頻繁,丟棄剛剛分配的分配似乎是浪費,並在下一個語句中立即分配另一個分配。 sun的工程師,顯然不信任GC那么多,創建了一個線程本地池“直接”ByteBuffers。

我認為你的案例是合理的情況使用匯集。 合並沒有邪惡,Goetz意味着你不應該在沒有必要時使用它。 另一個例子是連接池,因為連接的創建非常昂貴。

如果它是threadlocal,很可能你甚至不需要匯集。 當然它取決於用例,但是在給定的線程上你可能只需要在給定時間只有一個這種類型的對象。

然而,與threadlocals的警告是內存管理。 請注意,在擁有這些threadlocals的線程消失之前,threadlocal值不會輕易消失。 因此,如果你有大量的線程和大量的threadlocals,它們可能會對使用過的內存產生很大影響。

我肯定會嘗試一下。 雖然現在是“常識”,人們不應該關心對象創建,但實際上使用對象池和特定類可能會獲得很多性能。 對於文件處理框架,我從pooling object []對象中獲得了5%的讀取性能。

所以試試看你的執行時間,看看你是否獲得了任何收益。

即使這是一個老問題,2個線程請求池中的對象需要昂貴的同步並不完全適用。

可以編寫一個並發(無同步)對象池,它甚至不會在快速路徑上展示共享(甚至虛假共享)。 當然,在簡單的情況下,每個線程可能都有自己的池(更像是一個關聯的對象),但是這種貪婪的方法會導致資源浪費(如果無法分配資源,則會出現飢餓/錯誤)

游泳池適用於像ByteBuffers這樣的重物,特別是。 直接的,連接,套接字,線程等。總體上任何需要非Java干預的對象。

有效Java(第二版)中的 Joshua Bloch說:

靜態工廠方法的第二個優點是,與構造函數不同,它們不需要在每次調用時創建新對象。 這允許不可變類使用預構建的實例或在構造它們時緩存實例並重復分配這些實例,以避免創建不必要的重復對象。 Boolean.valueOf(boolean)方法說明了這種技術:它永遠不會創建一個對象。 如果經常請求等效對象,這種技術可以極大地提高性能,特別是如果這些對象的創建成本很高。

我會說這取決於。 如果它值得,那就去做吧。

暫無
暫無

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

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