成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深度剖析 C++ 對象池自動回收技術(shù)實(shí)現(xiàn)

開發(fā) 后端
對象池可以顯著提高性能,如果一個(gè)對象的創(chuàng)建非常耗時(shí)或非常昂貴,頻繁去創(chuàng)建的話會非常低效。對象池通過對象復(fù)用的方式來避免重復(fù)創(chuàng)建對象,它會事 先創(chuàng)建一定數(shù)量的對象放到池中,當(dāng)用戶需要創(chuàng)建對象的時(shí)候,直接從對象池中獲取即可,用完對象之后再放回到對象池中,以便復(fù)用。

對象池可以顯著提高性能,如果一個(gè)對象的創(chuàng)建非常耗時(shí)或非常昂貴,頻繁去創(chuàng)建的話會非常低效。對象池通過對象復(fù)用的方式來避免重復(fù)創(chuàng)建對象,它會事 先創(chuàng)建一定數(shù)量的對象放到池中,當(dāng)用戶需要創(chuàng)建對象的時(shí)候,直接從對象池中獲取即可,用完對象之后再放回到對象池中,以便復(fù)用。這種方式避免了重復(fù)創(chuàng)建耗 時(shí)或耗資源的大對象,大幅提高了程序性能。本文將探討對象池的技術(shù)特性以及源碼實(shí)現(xiàn)。

對象池類圖

  • ObjectPool:管理對象實(shí)例的pool。

  • Client:使用者。

適用性:

  • 類的實(shí)例可重用。

  • 類的實(shí)例化過程開銷較大。

  • 類的實(shí)例化的頻率較高。

效果:

  • 節(jié)省了創(chuàng)建類實(shí)例的開銷。

  • 節(jié)省了創(chuàng)建類實(shí)例的時(shí)間。

  • 存儲空間隨著對象的增多而增大。

問題

目前縱觀主流語言的實(shí)現(xiàn)方式無外乎3個(gè)步驟:

  1. 初始創(chuàng)建一定數(shù)量的對象池(也允許從外面添加對象)。

  2. 從對象池中取對象來使用。

  3. 用完之后返回對象池。

一般情況下這樣是OK的,可能存在的問題是在第三步,有兩個(gè)問題:

  1. 不方便,每次都需要顯式回收對象。

  2. 忘記將對象放回對象池,造成資源浪費(fèi)。

改進(jìn)動機(jī)

解決顯式回收的問題,實(shí)現(xiàn)自動回收,省心省力。改進(jìn)之后的對象池?zé)o須提供release方法,對象會自動回收,改進(jìn)之后的類圖如下。


技術(shù)內(nèi)幕

借助c++11智能指針,因?yàn)橹悄苤羔樋梢宰远x刪除器,在智能指針釋放的時(shí)候會調(diào)用刪除器,在刪除器中我們將用完的對象重新放回對象池。思路比較簡單,但實(shí)現(xiàn)的時(shí)候需要考慮兩個(gè)問題:

  1. 什么時(shí)候定義刪除器?

  2. 用shared_ptr還是unique_ptr?

1. 什么時(shí)候定義刪除器

自定義刪除器只做一件事,就是將對象重新放入對象池。如果對象池初始化的時(shí)候就自定義刪除器的話,刪除器中的邏輯是將對象放回對象池,放回的時(shí)候無 法再定義一個(gè)這樣的刪除器,所以這種做法行不通。需要注意,回收的對象只能是默認(rèn)刪除器的。除了前述原因之外,另外一個(gè)原因是對象池釋放的時(shí)候需要釋放所 有的智能指針,釋放的時(shí)候如果存在自定義刪除器將會導(dǎo)致對象無法刪除。只有在get的時(shí)候定義刪除器才行,但是初始創(chuàng)建或加入的智能指針是默認(rèn)刪除器,所 以我們需要把智能指針的默認(rèn)刪除器改為自定義刪除器。

1.2 用shared_ptr還是unique_ptr

因?yàn)槲覀冃枰阎悄苤羔樀哪J(rèn)刪除器改為自定義刪除器,用shared_ptr會很不方便,因?yàn)槟銦o法直接將shared_ptr的刪除器修改為自 定義刪除器,雖然你可以通過重新創(chuàng)建一個(gè)新對象,把原對象拷貝過來的做法來實(shí)現(xiàn),但是這樣做效率比較低。而unique_ptr由于是獨(dú)占語義,提供了一 種簡便的方法方法可以實(shí)現(xiàn)修改刪除器,所以用unique_ptr是最適合的。

1.3 實(shí)現(xiàn)源碼

 

  1. #pragma once 
  2. #include <memory> 
  3. #include <vector> 
  4. #include <functional> 
  5.  
  6. template <class T> 
  7. class SimpleObjectPool 
  8. public
  9.     using DeleterType = std::function<void(T*)>; 
  10.  
  11.     void add(std::unique_ptr<T> t) 
  12.     { 
  13.         pool_.push_back(std::move(t)); 
  14.     } 
  15.  
  16.     std::unique_ptr<T, DeleterType> get() 
  17.     { 
  18.         if (pool_.empty()) 
  19.         { 
  20.             throw std::logic_error("no more object"); 
  21.         } 
  22.  
  23.         //every time add custom deleter for default unique_ptr 
  24.         std::unique_ptr<T, DeleterType> ptr(pool_.back().release(), [this](T* t) 
  25.         { 
  26.             pool_.push_back(std::unique_ptr<T>(t)); 
  27.         }); 
  28.  
  29.         pool_.pop_back(); 
  30.         return std::move(ptr); 
  31.     } 
  32.  
  33.     bool empty() const 
  34.     { 
  35.         return pool_.empty(); 
  36.     } 
  37.  
  38.     size_t size() const 
  39.     { 
  40.         return pool_.size(); 
  41.     } 
  42.  
  43. private
  44.     std::vector<std::unique_ptr<T>> pool_; 
  45. }; 
  46.  
  47. //test code 
  48. void test_object_pool() 
  49.     SimpleObjectPool<A> p; 
  50.     p.add(std::unique_ptr<A>(new A())); 
  51.     p.add(std::unique_ptr<A>(new A())); 
  52.     { 
  53.         auto t = p.get(); 
  54.         p.get(); 
  55.     } 
  56.  
  57.     { 
  58.         p.get(); 
  59.         p.get(); 
  60.     } 
  61.  
  62.     std::cout << p.size() << std::endl; 
  63. } 

如果你堅(jiān)持用shared_ptr,那么回收的時(shí)候你需要這樣寫:

  1. std::shared_ptr<T> get() 
  2. if (pool_.empty()) 
  3.   throw std::logic_error("no more object"); 
  4.  
  5. std::shared_ptr<T> ptr = pool_.back(); 
  6. auto p = std::shared_ptr<T>(new T(std::move(*ptr.get())), [this](T* t) 
  7.   pool_.push_back(std::shared_ptr<T>(t)); 
  8. }); 
  9.  
  10. //std::unique_ptr<T, DeleterType> ptr(pool_.back().release(), [this](T* t) 
  11. //{ 
  12. // pool_.push_back(std::unique_ptr<T>(t)); 
  13. //}); 
  14.  
  15. pool_.pop_back(); 
  16. return p; 

這種方式需要每次都創(chuàng)建一個(gè)新對象,并且拷貝原來的對象,是一種比較低效的做法。代碼僅僅是為了展示如何實(shí)現(xiàn)自動回收對象,沒有考慮線程安全、對象池?cái)U(kuò)容策略等細(xì)節(jié),源碼鏈接:object_pool

總結(jié)凡是需要自動回收的場景下都可以使用這種方式:在獲取對象的時(shí)候?qū)⒛J(rèn)刪除器改為自定義刪除器,確保它可以回收。注意,回收的智能指針使用的是 默認(rèn)刪除器,可以確保對象池釋放時(shí)能正常釋放對象。同時(shí)也將獲取對象和釋放對象時(shí),對象的控制權(quán)完全分離。其他的一些應(yīng)用場景:多例模式,無需手動釋放, 自動回收。

責(zé)任編輯:王雪燕 來源: 祁宇
相關(guān)推薦

2021-08-29 22:05:04

對象自動回收

2010-01-28 16:31:54

C++類型

2010-01-15 10:32:21

C++語言

2010-01-26 14:46:42

C++語言

2010-01-13 13:42:55

C++編譯器

2010-01-26 17:16:33

C++應(yīng)用程序

2010-01-28 14:54:01

C++資源管理

2010-01-13 10:16:42

C++軟件

2010-01-27 15:50:23

C++復(fù)雜性

2012-02-17 10:50:10

Java

2023-02-21 15:26:26

自動駕駛特斯拉

2010-01-11 10:19:57

C++開發(fā)工具

2010-01-11 17:43:23

C++程序設(shè)計(jì)

2010-01-13 11:14:06

C++虛表

2010-01-12 15:03:33

C++代碼

2009-09-10 17:37:01

C# get post

2010-01-14 17:42:47

CC++

2010-02-03 16:56:24

Python包

2025-05-06 09:12:46

2010-02-02 13:22:06

Python面向?qū)ο?/a>
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美一区二区三区四区视频 | 日韩一区二区视频 | 国产精品a级 | 日本视频免费 | 亚洲久久 | 国产一区在线免费观看视频 | 日日干天天操 | 亚洲精品欧美 | 亚洲aⅴ | 99视频在线免费观看 | 亚洲精品中文字幕av | 午夜电影网站 | 久久成人精品 | 亚洲狠狠丁香婷婷综合久久久 | 国产日韩欧美激情 | 亚洲不卡在线观看 | 成人免费区一区二区三区 | 成年人黄色一级毛片 | 中国美女撒尿txxxxx视频 | 99热99| 欧美一级在线 | 国产一区二区不卡 | 日韩一区二区久久 | 国产成都精品91一区二区三 | 99亚洲 | 国产区精品视频 | 999热视频| 成人欧美一区二区三区黑人孕妇 | xxxxx黄色片 欧美一区免费 | www.亚洲一区二区三区 | 羞羞视频网站免费观看 | 亚洲一二三区av | 成年免费在线观看 | 精品久久久久久久久久久 | 亚洲国产高清高潮精品美女 | 黄视频在线网站 | 国产一区二区三区视频在线观看 | 成人一区在线观看 | 成人一区二区三区在线观看 | 狠狠ri | 夜夜爽夜夜操 |