中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

煙臺h5網站建設公司游戲代理免費加盟

煙臺h5網站建設公司,游戲代理免費加盟,甘肅省人民政府最新任命公告,龍巖app開發(fā)定制目錄 定長內存池設計設計思路具體實現(xiàn)定長內存池初始化T*New()申請內存代碼 void Delete(T* obj)回收內存代碼 設計的總代碼測試代碼 Objectpool.h文件代碼test.cpp文件代碼拓展windows和Linux下如何直接向堆申請頁為單位的大塊內存: 感謝各位大佬對我的支持,如果我…

目錄

  • 定長內存池設計
    • 設計思路
      • 具體實現(xiàn)
        • 定長內存池初始化
          • T*New()申請內存
            • 代碼
          • void Delete(T* obj)回收內存
            • 代碼
          • 設計的總代碼
          • 測試代碼
  • Objectpool.h文件代碼
  • test.cpp文件代碼
  • 拓展windows和Linux下如何直接向堆申請頁為單位的大塊內存:

感謝各位大佬對我的支持,如果我的文章對你有用,歡迎點擊以下鏈接
🐒🐒🐒 個人主頁
🥸🥸🥸 C語言
🐿?🐿?🐿? C語言例題
🐣🐣🐣 python
🐓🐓🐓 數據結構C語言
🐔🐔🐔 C++
🐿?🐿?🐿? 文章鏈接目錄
🤠🤠🤠 高并發(fā)內存池項目

定長內存池設計

設計思路

申請一大塊內存,用一個指針指向申請的內存,這里的難點是內存釋放,因為我們申請的是一塊很大的內存,而使用的時候都是將這一大塊內存切成一小塊一小塊的用,而用完后釋放我們不可以直接將他還給系統(tǒng),因為釋放的內存太小了,如果還給系統(tǒng)就會出現(xiàn)內存碎片的問題,所以我們是要將需要釋放的內存管理起來,當他們都釋放后再歸還內存,這里的管理方式就是用一個鏈表將內存管理起來
在這里插入圖片描述
由于是定長內存池,這里的定長就是切固定大小的內存

具體實現(xiàn)

定長內存池初始化

首先我們需要一個類

class Objectpool
{};

由于是定長內存池,所以類里面一點要有一個指針指向申請的內存空間,為了方便切割內存我們使用char*_memory,因為char是可以精確到1個字節(jié)1個字節(jié)的切割比較方便,如果是int的話那么我們要切割的長度就是4的倍數
此外因為申請內存是固定的我們可以用非類型的模版參數template<size_t N>表示我們申請的內存是一個固定大小為N
當然我們也可以用template表示ObjectPool每次獲取的對象都是一個T對象,T的大小是固定的,這里我們選擇的是用template

template<class T>
class ObjectPool
{char* _memory=nullptr;
};

我們還需要考慮內存回收
在這里插入圖片描述
當我們需要切割內存時_memory需要往后移動
在這里插入圖片描述

在這里插入圖片描述
當切割后的內存用完后需要回收我們需要用一個鏈表將他們串起來
在這里插入圖片描述
在這里插入圖片描述
可是現(xiàn)在有一個問題我們應該怎么樣才能將他們串起來,我們是否需要再定義一個結構體將他們鏈接起來呢?

其實是不需要的,我們可以直接在內存當中修改,將后面的內存塊地址存到前一個內存塊當中,但是這里有一個要求就是32位下的指針大小是4個字節(jié),而64位下的指針大小是8個字節(jié),也就意味著當我們要存一個內存塊的空間時,32位下內存塊至少要有4個字節(jié),而64位則至少要有8個字節(jié)

在32位下對于一個內存塊有100字節(jié)我們則需要將他的頭4個字節(jié)進行修改保存下一塊內存的地址
在這里插入圖片描述

T*New()申請內存

申請內存我們需要先看_memory是否為空,如果_memory為空的話那么就需要申請內存

T* New()
{if (_memory==nullptr)//剩余內存不夠一個對象大小是重新開大塊空間{_memory =(char*) malloc(128 * 1024);//128kbif (_memory == nullptr){throw std::bad_alloc();}}T* obj = (T*)_memory;_memory += sizeof(T);return obj;
}

如果申請后_memory仍為空那么就拋異常,反之就讓一個對象obj指向申請內存的空間
_memory += sizeof(T)就表示的切割空間,讓_memory切割 sizeof(T)大小的空間
在這里插入圖片描述

這里有一個問題就是_memory走到最后的時候,如果_memory繼續(xù)+= sizeof(T)就會造成越界,因為申請的內存以及用完了,而_memory現(xiàn)在在訪問的是別的空間
在這里插入圖片描述
在這里插入圖片描述
為了解決這個問題我們還需要有一個remainBytes去記錄還剩多少空間,當remainBytes<sizeof(T)的時候就意味著剩下的空間以及不足以支持我們繼續(xù)切割了,可能需要重新申請一塊空間

為什么是可能需要重新申請一塊空間呢,因為_freeList是回收釋放的內存,如果_freeList中有回收了的內存,那么這些內存是可以繼續(xù)重復利用的
所以一開始需要一個指針next保存_freeList前面記錄下來的位置,然后讓obj指向_freeList,再讓_freeList=next

	T* obj = nullptr;if (_freeList){void* next = *((void**))_freeList);obj = (T*)_freeList;//因為obj是T*,所以_freeList也要強轉_freeList = next;}

void* next = * ((void**))_freeList)這段代碼會在下面部分解釋
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
還有一個問題就是sizeof(T)大小問題,因為這是一個類模版,如果T是char類型的話他的內存是小于4個字節(jié)的,int類型的話也就剛好4個字節(jié),但是在64位下是不夠的,所以需要判斷sizeof(T) < sizeof(void*) ,表示T的內存大小是否小于一個指針,如果小于的話就要更改切割內存的大小
最后我們還需要對我們創(chuàng)造的對象進行初始化
這里用定位new顯示調用T的構造函數初始化new(obj)T

代碼
	T* New(){T* obj = nullptr;if (_freeList){void* next = *((void**))_freeList);obj =(T*) _freeList;_freeList = next;}else{if (_remainBytes < sizeof(T))//剩余內存不夠一個對象大小是重新開大塊空間{_remainBytes = 128 * 1024;_memory = (char*)malloc(_remainBytes);//128kbif (_memory == nullptr){throw std::bad_alloc();}}obj = (T*)_memory;size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);//因為T是一個類模版,當T是char或int時可能會導致內存不足以存儲一個地址_memory += objSize;_remainBytes -= objSize;}new(obj)T;//定位new顯示調用T的構造函數初始化return obj;}
void Delete(T* obj)回收內存

在最開始的時候_freeList是指向的空
在這里插入圖片描述
當第一次有空間回收時,我們要讓空間的前4個字節(jié)存空地址,具體辦法就是讓傳入的指針強轉成int*,那么我們對int進行解引用將前4個字節(jié)更改為nullptr就可以實現(xiàn)了
在這里插入圖片描述
但是這里有一個問題就是int
只有4個字節(jié),這種方法只適用于32位下,在64位下是不行的
當然我們可以用if語句判斷一個指針的大小,然后再進行細分也是可以的
下面有更簡單的方式就是將obj強轉成void**,也就是二級指針(其他類型的二級指針也是可以的,主要用的就是二級指針轉換成一級指針的空間大小是4/8個字節(jié)),然后我們對他解引用,*(void**)obj = nullptr

上面是解決第一次內存塊回收的問題,下面是解決多次回收的問題
在這里插入圖片描述

多個內存塊回收我們選擇用頭插的方式串起來,因為尾插效率太低
在這里插入圖片描述
首先還是要讓新的內存塊保存_freeList指向的地址,然后讓_freeList指向新的內存塊
在這里插入圖片描述
在這里插入圖片描述

void Delete(T* obj)
{if (_freeList==nullptr){_freeList = obj;*(void**)obj = nullptr;}else{*(void**)obj = _freeList;_freeList = obj;}
}

我們發(fā)現(xiàn)上面代碼中

*(void**)obj = _freeList;_freeList = obj;

這段代碼是適用于所有情況的
一開始_freeList=nullptr
在這里插入圖片描述
讓obj前4/8個字節(jié)保存_freeList
在這里插入圖片描述
然后讓_freeList指向obj
在這里插入圖片描述
即使有新回收的也是適用的
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

代碼
void Delete(T* obj)
{obj->~T();//顯示調用析構函數*(void**)obj = _freeList;_freeList = obj;
}
設計的總代碼
template<class T>
class ObjectPool
{
public:T* New(){T* obj = nullptr;if (_freeList){void* next = *((void**)_freeList);obj =(T*) _freeList;_freeList = next;}else{if (_remainBytes < sizeof(T))//剩余內存不夠一個對象大小是重新開大塊空間{_remainBytes = 128 * 1024;_memory = (char*)malloc(_remainBytes);//128kbif (_memory == nullptr){throw std::bad_alloc();}}obj = (T*)_memory;size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);_memory += objSize;_remainBytes -= objSize;}new(obj)T;return obj;}void Delete(T* obj){obj->~T();*(void**)obj = _freeList;_freeList = obj;}
private:char* _memory = nullptr;//指向大塊內存的指針void* _freeList = nullptr;//還回過程中鏈接的自由鏈表頭指針size_t _remainBytes = 0;//大塊內存切割過程中的剩余字節(jié)數
};
測試代碼
struct TreeNode
{int _val;TreeNode* _left;TreeNode* _right;TreeNode():_val(0), _left(nullptr), _right(nullptr){}
};
void TestObjectPool()
{// 申請釋放的輪次const size_t Rounds = 5;// 每輪申請釋放多少次const size_t N = 100000;std::vector<TreeNode*> v1;v1.reserve(N);size_t begin1 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v1.push_back(new TreeNode);}for (int i = 0; i < N; ++i){delete v1[i];}v1.clear();}size_t end1 = clock();std::vector<TreeNode*> v2;v2.reserve(N);ObjectPool<TreeNode> TNPool;size_t begin2 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v2.push_back(TNPool.New());}for (int i = 0; i < N; ++i){TNPool.Delete(v2[i]);}v2.clear();}size_t end2 = clock();cout << "new cost time:" << end1 - begin1 << endl;cout << "object pool cost time:" << end2 - begin2 << endl;
}

Objectpool.h文件代碼

#include<iostream>
#include<vector>
#include<time.h>
using std::cout;
using std::endl;
template<class T>
class ObjectPool
{
public:T* New(){T* obj = nullptr;if (_freeList){void* next = *((void**)_freeList);obj =(T*) _freeList;_freeList = next;}else{if (_remainBytes < sizeof(T))//剩余內存不夠一個對象大小是重新開大塊空間{_remainBytes = 128 * 1024;_memory = (char*)malloc(_remainBytes);//128kbif (_memory == nullptr){throw std::bad_alloc();}}obj = (T*)_memory;size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);_memory += objSize;_remainBytes -= objSize;}new(obj)T;return obj;}void Delete(T* obj){obj->~T();*(void**)obj = _freeList;_freeList = obj;}
private:char* _memory = nullptr;//指向大塊內存的指針void* _freeList = nullptr;//還回過程中鏈接的自由鏈表頭指針size_t _remainBytes = 0;//大塊內存切割過程中的剩余字節(jié)數
};
struct TreeNode
{int _val;TreeNode* _left;TreeNode* _right;TreeNode():_val(0), _left(nullptr), _right(nullptr){}
};
void TestObjectPool()
{// 申請釋放的輪次const size_t Rounds = 5;// 每輪申請釋放多少次const size_t N = 100000;std::vector<TreeNode*> v1;v1.reserve(N);size_t begin1 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v1.push_back(new TreeNode);}for (int i = 0; i < N; ++i){delete v1[i];}v1.clear();}size_t end1 = clock();std::vector<TreeNode*> v2;v2.reserve(N);ObjectPool<TreeNode> TNPool;size_t begin2 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v2.push_back(TNPool.New());}for (int i = 0; i < N; ++i){TNPool.Delete(v2[i]);}v2.clear();}size_t end2 = clock();cout << "new cost time:" << end1 - begin1 << endl;cout << "object pool cost time:" << end2 - begin2 << endl;
}

test.cpp文件代碼

#include"Objectpool.h"
int main()
{TestObjectPool();return 0;  
}

拓展windows和Linux下如何直接向堆申請頁為單位的大塊內存:

VirtualAlloc
Linux進程分配內存的兩種方式–brk() 和mmap()

http://www.risenshineclean.com/news/11625.html

相關文章:

  • 專門做恐怖電影網站谷歌排名推廣
  • 做網站的顏色搭配網絡優(yōu)化seo薪酬
  • 查詢網站備案號qq排名優(yōu)化網站
  • 網站服務器 內存seo怎么才能做好
  • 做網站的如何找客戶平臺引流推廣怎么做
  • 做網站可以賺錢嗎?atp最新排名
  • 農村網站建設百度上怎么免費開店
  • 設置本機外網ip做網站技術培訓
  • 做線下活動的網站泉州百度關鍵詞排名
  • 可做生物試卷的網站站長統(tǒng)計在線觀看
  • 高端網站開發(fā)企業(yè)百度百度一下
  • 有做自由行包車的網站qq群推廣網站免費
  • 大理北京網站建設app開發(fā)定制
  • 青島app網站開發(fā)企業(yè)網站建設價格
  • 唐河做網站網站推廣鄭州
  • 如何選擇贛州網站建設網站關鍵詞排名服務
  • 長沙app下載seo網站推廣實例
  • 網站運營隊伍與渠道建設網站的宣傳與推廣
  • wordpress問答社區(qū)模板合肥seo整站優(yōu)化網站
  • 自己做pc網站建設seo教學視頻教程
  • 開80服務器怎么做網站網站設計的基本原則
  • 泰州做網站哪家好自動化測試培訓機構哪個好
  • 建站時網站地圖怎么做網絡推廣員一個月多少錢
  • 用php做網站用什么框架百度域名查詢官網
  • 做網站開發(fā)有哪些優(yōu)點呢百度賬號快速注冊
  • 做淘寶網站如何提取中間的提成2024年新聞摘抄
  • 北京景觀設計公司長春網絡優(yōu)化哪個公司在做
  • 軟件工程就業(yè)方向什么是網站推廣優(yōu)化
  • html網站標題怎么做百度如何購買關鍵詞
  • 哪個網站可以做信用社的題免費發(fā)布推廣的網站