深度剖析C++對象池自動回收技術(shù)實現(xiàn)
摘要:對象池可以顯著提高性能,如果一個對象的創(chuàng)建非常耗時或非常昂貴,頻繁去創(chuàng)建的話會非常低效。本文將探討對象池的技術(shù)特性以及源碼實現(xiàn)。
對象池可以顯著提高性能,如果一個對象的創(chuàng)建非常耗時或非常昂貴,頻繁去創(chuàng)建的話會非常低效。對象池通過對象復(fù)用的方式來避免重復(fù)創(chuàng)建對象,它會事先創(chuàng)建一定數(shù)量的對象放到池中,當用戶需要創(chuàng)建對象的時候,直接從對象池中獲取即可,用完對象之后再放回到對象池中,以便復(fù)用。這種方式避免了重復(fù)創(chuàng)建耗時或耗資源的大對象,大幅提高了程序性能。本文將探討對象池的技術(shù)特性以及源碼實現(xiàn)。
對象池類圖
ObjectPool:管理對象實例的pool。Client:使用者。
適用性:
類的實例可重用。類的實例化過程開銷較大。類的實例化的頻率較高。
效果:
節(jié)省了創(chuàng)建類實例的開銷。節(jié)省了創(chuàng)建類實例的時間。存儲空間隨著對象的增多而增大。
問題?
目前縱觀主流語言的實現(xiàn)方式無外乎3個步驟:
初始創(chuàng)建一定數(shù)量的對象池(也允許從外面添加對象)。從對象池中取對象來使用。用完之后返回對象池。
一般情況下這樣是OK的,可能存在的問題是在第三步,有兩個問題:
不方便,每次都需要顯式回收對象。忘記將對象放回對象池,造成資源浪費。
改進動機?
解決顯式回收的問題,實現(xiàn)自動回收,省心省力。改進之后的對象池無須提供release方法,對象會自動回收,改進之后的類圖如下。
技術(shù)內(nèi)幕
借助c++11智能指針,因為智能指針可以自定義刪除器,在智能指針釋放的時候會調(diào)用刪除器,在刪除器中我們將用完的對象重新放回對象池。思路比較簡單,但實現(xiàn)的時候需要考慮兩個問題:
什么時候定義刪除器?用shared_ptr還是unique_ptr??1. 什么時候定義刪除器
自定義刪除器只做一件事,就是將對象重新放入對象池。如果對象池初始化的時候就自定義刪除器的話,刪除器中的邏輯是將對象放回對象池,放回的時候無法再定義一個這樣的刪除器,所以這種做法行不通。需要注意,回收的對象只能是默認刪除器的。除了前述原因之外,另外一個原因是對象池釋放的時候需要釋放所有的智能指針,釋放的時候如果存在自定義刪除器將會導致對象無法刪除。只有在get的時候定義刪除器才行,但是初始創(chuàng)建或加入的智能指針是默認刪除器,所以我們需要把智能指針的默認刪除器改為自定義刪除器。?
1.2 用shared_ptr還是unique_ptr
因為我們需要把智能指針的默認刪除器改為自定義刪除器,用shared_ptr會很不方便,因為你無法直接將shared_ptr的刪除器修改為自定義刪除器,雖然你可以通過重新創(chuàng)建一個新對象,把原對象拷貝過來的做法來實現(xiàn),但是這樣做效率比較低。而unique_ptr由于是獨占語義,提供了一種簡便的方法方法可以實現(xiàn)修改刪除器,所以用unique_ptr是最適合的。?
1.3 實現(xiàn)源碼
[cpp]?view plaincopy #pragma?once?? #include?