回答
只有兩種類型的資源我能想到,通常是合併的:線程和連接(即數據庫)。
這兩個都有一個首要問題:缺乏。
- 如果創建了太多的線程,上下文切換會浪費掉所有的CPU時間。
- 如果創建了太多的網絡連接,維護這些連接的開銷比任何連接所要做的都要多。
- 另外,對於數據庫,由於授權原因,連接數可能會受到限制。
因此,您希望創建資源池的主要原因是,如果您只能負擔在任何時候都有限的數量。
- 當對象的創建是昂貴
- 當你可能會遇到內存壓力 - 太多的對象(例如 - 享元模式)
我想補充內存碎片到列表中。在使用封裝本地資源的對象時,可能會發生這種情況,這些資源在分配之後無法由垃圾收集器移動並可能將堆碎片化。
一個現實生活中的例子是當你創建並銷燬大量的套接字時。他們用來讀/寫數據的緩衝區必須被固定,才能被傳送到本地WinSock API,這意味着當發生垃圾收集時,即使某些內存被銷燬的套接字回收 - 它可能會使內存處於碎片狀態,因爲GC無法在收集後壓縮堆。因此,讀/寫緩衝區是池的主要候選者。另外,如果你使用SocketEventArgs對象,那些對象也是很好的選擇。
這是一個good article,它討論垃圾收集過程,內存壓縮以及爲什麼對象池有幫助。
有一篇很棒的MSDN雜誌文章,名爲Erik Brown http://msdn.microsoft.com/en-us/magazine/cc163856.aspx,在您的託管代碼中重新發現內存優化的失落藝術。它包含一個帶有測試程序的通用對象池。該對象池確實支持最小和最大尺寸。我找不到任何對使用此功能的人的引用。有沒有人這樣做?另外,在處理ASP.NET應用程序中的內存碎片之後,我可以證明Miky Dinescu的答案中的值。另外,對Vitaly的答案稍作闡述,考慮大型對象(即> 85K)的情況,這些對象的創建成本很高。大對象只參與第2代垃圾收集。這意味着它們不會像完全參與第0代和第1代垃圾收集的對象一樣快速收集。本文Maoni Stephens發現的大對象堆 (http://msdn.microsoft.com/en-us/magazine/cc534993.aspx)詳細解釋了大型對象堆。
對於遊戲GC可能在某些情況下引入不必要的延遲。如果是這種情況,重複使用對象可能是一個好主意。關於this thread中的主題有一些有用的考慮。
- 1. Flyweight vs對象池模式:什麼時候有用?
- 2. 什麼時候發佈「autorelease」對象?
- 3. 什麼時候創建了String對象?
- 4. 什麼時候證書對象失效?
- 5. 什麼時候快速刪除對象?
- 6. PHP對象什麼時候死?
- 7. 什麼時候處理圖形對象
- 8. 什麼時候流對象被刪除?
- 9. 我什麼時候需要序列化一個對象?
- 10. 什麼時候在這種情況下實例化對象?
- 11. 我應該什麼時候初始化對象
- 12. 什麼時候去接口,什麼時候去抽象類
- 13. 爲什麼和什麼時候我們需要扁平化JSON對象?
- 14. 什麼時候需要在java中初始化一個對象,什麼時候不需要?
- 15. 什麼時候應該使用Satellite Assemblies進行本地化?什麼時候應該使用資源文件(.resx)?
- 16. 什麼時候python對象是垃圾收集的候選對象?
- 17. struts2創建會話對象,爲什麼和什麼時候?
- 18. 什麼是謙虛對象模式,什麼時候有用?
- 19. 什麼是JavaScript對象,它們什麼時候有用?
- 20. 對象的值是什麼,什麼時候可以爲空?
- 21. 什麼時候進行索引,在Mongoid中索引什麼?
- 22. 爲什麼要對Json對象進行爆炸序列化?
- 23. 什麼時候autoexec.sas執行
- 24. Andengine - 對象池或通用池優化
- 25. MongoDB:多對多 - 什麼時候執行非規範化vs規範化?
- 26. 什麼時候應該使用/不使用池化和非池化的數據庫連接?
- 27. 對象池化框架
- 28. 什麼時候對自動釋放對象遞減計數?
- 29. 什麼時候使對象爲零,何時調用realese
- 30. 什麼時候在oracle中重新編譯時鎖定對象