IOCP之内存分配池[1]
来源:互联网 发布:mac pro 无线网卡 编辑:程序博客网 时间:2024/05/10 02:27
http://blog.csdn.net/im17benteng/article/details/7167831
{******************************************************************************}{ @UnitName : uVirtualMemPool.pas }{ @Project : QsIOCP }{ @Copyright : - }{ @Author : 奔腾的心(7180001) }{ @Description : 分页式虚拟内存管理 }{ @FileVersion : 1.0.0.0 }{ @CreateDate : 2011-07-16 }{ @Comment : - }{ @LastUpdate : 2011-07-20 }{******************************************************************************}unit uVirtualMemPool;interfaceuses SysUtils, Windows;type TVirtualMemPool = class; PSBTNode = ^TSBTNode; TSBTNode = record IsUse: Boolean; count: Cardinal; value: Pointer; data: Cardinal; size: Cardinal; lch,rch: PSBTNode; end; // 平衡二叉查找树SBT TSizeBalancedTree = class private VMPool: TVirtualMemPool; // 节点数 NodeCount: Cardinal; // 根节点,空节点 root,null: PSBTNode; // 左旋转 procedure lrotate(var x: PSBTNode); inline; // 右旋转 procedure rrotate(var x: PSBTNode); inline; // 保持性质 procedure maintain(var t: PSBTNode; const flag: Boolean); inline; // 增加 procedure TreeAdd(var t: PSBTNode; v: PSBTNode); inline; // 移除 function TreeRemove(var t: PSBTNode; var n: PSBTNode; v: Cardinal): Cardinal; inline; // 返回第 x 大的元素 function TreeSelect(var t: PSBTNode; k: Cardinal; var r: Cardinal): Cardinal; inline; // 查找 function TreeFind(var t: PSBTNode; v: Cardinal): Boolean; inline; // 排名 function TreeRank(var t: PSBTNode; v: Cardinal): Cardinal; inline; // 向前,大 function TreeSucc(var t: PSBTNode; v: Cardinal): Cardinal; inline; // 向后,小 function TreePred(var t: PSBTNode; v: Cardinal): Cardinal; inline; public constructor Create(AVMpool: TVirtualMemPool); destructor Destroy; override; procedure add(v: PSBTNode); function remove(v: Cardinal): PSBTNode; function select(k: Cardinal): Cardinal; inline; function find(v: Cardinal): Boolean; inline; function rank(v: Cardinal): Cardinal; inline; function succ(v: Cardinal): Cardinal; inline; function pred(v: Cardinal): Cardinal; inline; end; // 内存管理 TVirtualMemPool = class private m_VMLock: TRTLCriticalSection; m_NMLock: TRTLCriticalSection; m_PageSize: Cardinal; m_Count: Cardinal; m_UseHeightCount: Cardinal; m_lpBase: Pointer; m_Buckets: array of PSBTNode; m_SBTStorage: TSizeBalancedTree; private function GetCount: Cardinal; function GetUseCount: Cardinal; function GetFreeCount: Cardinal; function GetUseHeightCount: Cardinal; procedure InitMemPool(ACount: Integer); procedure Clear; public property Count: Cardinal read GetCount; property UseCount: Cardinal read GetUseCount; property FreeCount: Cardinal read GetFreeCount; property UseHeightCount: Cardinal read GetUseHeightCount; public constructor Create(ACount: Integer); destructor Destroy; override; public function VMAlloc(dwSize: Cardinal; IsLock: Boolean = True): Pointer; function VMReAlloc(var P; dwSize: Cardinal): Pointer; function VMFree(var P; IsLock: Boolean = True): Boolean; end;implementation{ TSizeBalancedTree }constructor TSizeBalancedTree.Create(AVMpool: TVirtualMemPool);begin VMPool := AVMpool; NodeCount := 0; new(null); null^.data := Cardinal(-1); null^.size := 0; null^.lch := null; null^.rch := null; root := null;end;destructor TSizeBalancedTree.Destroy;begin NodeCount := 0; Dispose(null); inherited Destroy;end;procedure TSizeBalancedTree.lrotate(var x: PSBTNode);var y: PSBTNode;begin y := x^.rch; x^.rch := y^.lch; y^.lch := x; y^.size := x^.size; x^.size := x^.lch^.size+x^.rch^.size+1; x := y;end;procedure TSizeBalancedTree.rrotate(var x: PSBTNode);var y: PSBTNode;begin y := x^.lch; x^.lch := y^.rch; y^.rch := x; y^.size := x^.size; x^.size := x^.lch^.size+x^.rch^.size+1; x := y;end;procedure TSizeBalancedTree.maintain(var t: PSBTNode; const flag: Boolean);begin if t=null then exit; if not flag then if t^.lch^.lch^.size>t^.rch^.size then rrotate(t) else if t^.lch^.rch^.size>t^.rch^.size then begin lrotate(t^.lch); rrotate(t); end else exit else if t^.rch^.rch^.size>t^.lch^.size then lrotate(t) else if t^.rch^.lch^.size>t^.lch^.size then begin rrotate(t^.rch); lrotate(t); end else exit; maintain(t^.lch, false); maintain(t^.rch, true); maintain(t, false); maintain(t, true);end;procedure TSizeBalancedTree.TreeAdd(var t: PSBTNode; v: PSBTNode);begin if v^.IsUse=False then Exit; if t=null then begin t := v; //进入的内存设置为未使用 t^.IsUse := False; t^.count := 0; t^.size := 1; t^.lch := null; t^.rch := null; Inc(NodeCount); end else begin inc(t^.size); if v^.data<t^.data then TreeAdd(t^.lch, v) else TreeAdd(t^.rch, v); maintain(t, v^.data>=t^.data); end;end;function TSizeBalancedTree.TreeRemove(var t: PSBTNode; var n: PSBTNode; v: Cardinal): Cardinal;var tmp: PSBTNode;begin //Result := Cardinal(-1); dec(t^.size); if(v=t^.data) or ((v<t^.data) and (t^.lch=null)) or ((v>t^.data) and (t^.rch=null)) then begin Result := t^.data; if(t^.lch=null) or (t^.rch=null) then begin if t^.lch=null then begin tmp := t; t := tmp^.rch; if tmp<>null then begin n := tmp; Dec(NodeCount); Exit; end; end; if t^.rch=null then begin tmp := t; t := tmp^.lch; if tmp<>null then begin n := tmp; Dec(NodeCount); Exit; end; end; end else t^.data := TreeRemove(t^.lch, n, t^.data+1); end else if v<t^.data then Result := TreeRemove(t^.lch, n, v) else Result := TreeRemove(t^.rch, n, v);end;function TSizeBalancedTree.TreeSelect(var t: PSBTNode; k: Cardinal; var r: Cardinal): Cardinal;begin if t=null then begin Result := Cardinal(-1); Exit; end; Inc(r); if (k=t^.lch^.size+1) then begin Result := t^.data; exit; end; if k<=t^.lch^.size then Result := TreeSelect(t^.lch, k, r) else Result := TreeSelect(t^.rch, k-1-t^.lch^.size, r);end;function TSizeBalancedTree.TreeFind(var t: PSBTNode; v: Cardinal): Boolean;begin if t=null then begin Result := false; exit; end; if v<t^.data then Result := TreeFind(t^.lch,v) else Result := (v=t^.data) or TreeFind(t^.rch,v);end;function TSizeBalancedTree.TreeRank(var t: PSBTNode; v: Cardinal): Cardinal;begin if t=null then begin Result := 1; exit; end; if v<t^.data then Result := TreeRank(t^.lch,v) else Result := t^.lch^.size+1+TreeRank(t^.rch,v);end;function TSizeBalancedTree.TreeSucc(var t: PSBTNode; v: Cardinal): Cardinal;var tmp:Cardinal;begin if t=null then begin Result := v; exit; end; if v>=t^.data then Result := TreeSucc(t^.rch,v) else begin tmp:=TreeSucc(t^.lch,v); if tmp=v then tmp := t^.data; Result := tmp; end;end;function TSizeBalancedTree.TreePred(var t: PSBTNode; v: Cardinal): Cardinal;var tmp: Cardinal;begin if t=null then begin Result := v; exit; end; if v<=t^.data then Result := TreePred(t^.lch, v) else begin tmp := TreePred(t^.rch,v); if tmp=v then tmp := t^.data; Result := tmp; end;end;procedure TSizeBalancedTree.add(v: PSBTNode);begin TreeAdd(root, v);end;function TSizeBalancedTree.remove(v: Cardinal): PSBTNode;var v2: Cardinal; C: Pointer; P: PSBTNode;begin Result := nil; TreeRemove(root, Result, v); if Result=nil then Exit; v2 := Result^.data; Result^.data := v; //移出的内存设置为使用 Result^.IsUse := True; //value交换 C := VMPool.m_Buckets[v2]^.value; VMPool.m_Buckets[v2]^.value := VMPool.m_Buckets[v]^.value; VMPool.m_Buckets[v]^.value := C; //位置交换 P := VMPool.m_Buckets[v2]; VMPool.m_Buckets[v2] := VMPool.m_Buckets[v]; VMPool.m_Buckets[v] := P;end;function TSizeBalancedTree.select(k: Cardinal): Cardinal;var R: Cardinal;begin R := 0; if root=null then begin Result := Cardinal(-1); Exit; end; Result := TreeSelect(root, k, R);end;function TSizeBalancedTree.find(v: Cardinal): Boolean;begin Result := TreeFind(root, v);end;function TSizeBalancedTree.rank(v: Cardinal): Cardinal;begin Result := TreeRank(root, v);end;function TSizeBalancedTree.succ(v: Cardinal): Cardinal;begin Result := TreeSucc(root, v);end;function TSizeBalancedTree.pred(v: Cardinal): Cardinal;begin Result := TreePred(root, v);end;{ TVirtualMemPool }constructor TVirtualMemPool.Create(ACount: Integer);var SysInfo: TSystemInfo;begin inherited Create;; InitializeCriticalSection(m_VMLock); InitializeCriticalSection(m_NMLock); GetSystemInfo(SysInfo); m_PageSize := SysInfo.dwPageSize; m_SBTStorage := TSizeBalancedTree.Create(Self); m_Count := ACount; m_UseHeightCount := 0; InitMemPool(m_Count);end;destructor TVirtualMemPool.Destroy;begin FreeAndNil(m_SBTStorage); Clear; VirtualFree(m_lpBase, 0, MEM_RELEASE); DeleteCriticalSection(m_NMLock); DeleteCriticalSection(m_VMLock); inherited Destroy;end;function TVirtualMemPool.GetCount: Cardinal;begin Result := m_Count;end;function TVirtualMemPool.GetUseCount: Cardinal;begin EnterCriticalSection(m_NMLock); try Result := m_Count - m_SBTStorage.NodeCount; finally LeaveCriticalSection(m_NMLock); end;end;function TVirtualMemPool.GetFreeCount: Cardinal;begin EnterCriticalSection(m_NMLock); try Result := m_SBTStorage.NodeCount; finally LeaveCriticalSection(m_NMLock); end;end;function TVirtualMemPool.GetUseHeightCount: Cardinal;begin if m_UseHeightCount<GetUseCount then m_UseHeightCount := GetUseCount; Result := m_UseHeightCount;end;procedure TVirtualMemPool.InitMemPool(ACount: Integer);var I: Integer;begin EnterCriticalSection(m_VMLock); try // 申请大块内存 m_lpBase := VirtualAlloc(nil, ACount*m_PageSize, MEM_RESERVE, PAGE_NOACCESS); SetLength(m_Buckets, ACount); //debug('m_lpBase: %d, NumberOfNode: %d', [Cardinal(m_lpBase), NumberOfNode]); for I := 0 to ACount-1 do begin { 为第I页地址提交内存。 } New(m_Buckets[I]); m_Buckets[I]^.IsUse := True; m_Buckets[I]^.data := I; m_Buckets[I]^.value := VirtualAlloc(Pointer(Cardinal(m_lpBase)+(I*m_PageSize)), m_PageSize, MEM_COMMIT, PAGE_READWRITE); //debug('I: %d=%d', [I, Cardinal(m_Buckets[I]^.value)]); //ZeroMemory(m_Buckets[I]^.value, m_PageSize); m_SBTStorage.add(m_Buckets[I]); end; finally LeaveCriticalSection(m_VMLock); end;end;procedure TVirtualMemPool.Clear;var I: Integer;begin EnterCriticalSection(m_VMLock); try for I := 0 to Length(m_Buckets)-1 do begin Dispose(m_Buckets[I]); end; finally LeaveCriticalSection(m_VMLock); end;end;function TVirtualMemPool.VMAlloc(dwSize: Cardinal; IsLock: Boolean = True): Pointer;var N, M, D1, D2, NStart, NEnd: Integer; P: PSBTNode;begin if FreeCount<=0 then begin raise Exception.Create('No free pages in main memory.'); Exit; end; if IsLock then EnterCriticalSection(m_VMLock); try N := dwSize div m_PageSize; if (dwSize mod m_PageSize)<>0 then Inc(N); M := 1; D2 := -1; D1 := m_SBTStorage.select(1); if D1<0 then begin Result := nil; Exit; end; if N<=1 then begin NStart := D1; //移出使用中的对像 P := m_SBTStorage.remove(NStart); if P=nil then begin Result := nil; Exit; end; P^.count := 1; Result := P^.value; Exit; end; while True do begin //右旋转 D2 := m_SBTStorage.succ(D1); if D2=D1 then Break; if D2=D1+1 then begin Inc(M); end else begin M := 1; end; if M>=N then Break; D1 := D2; end; NStart := D2 - N + 1; NEnd := NStart + N; P := m_SBTStorage.remove(NStart); P^.count := N; Result := P^.value; Inc(NStart); while NStart<NEnd do begin m_SBTStorage.remove(NStart); Inc(NStart); end; finally if IsLock then LeaveCriticalSection(m_VMLock); end;end;function TVirtualMemPool.VMReAlloc(var P; dwSize: Cardinal): Pointer;var OldN, M, NewN, NEnd: Cardinal; NewP: Pointer;begin Result := nil; if Pointer(P)=nil then begin Result := VMAlloc(dwSize); Exit; end; EnterCriticalSection(m_VMLock); try M := (Cardinal(Pointer(P))-Cardinal(m_lpBase)) div m_PageSize; // 原页数 OldN := m_Buckets[M]^.count; // 新页数 NewN := dwSize div m_PageSize; if (dwSize mod m_PageSize)<>0 then Inc(NewN); // 新页数=原页数 if NewN=OldN then begin Result := Pointer(P); end // 新页数<原页数,多余的页放回页表 else if NewN<OldN then begin NEnd := M + OldN; m_Buckets[M]^.count := OldN-NewN; M := M + NewN; while M<NEnd do begin m_SBTStorage.add(m_Buckets[M]); Inc(M); end; Result := Pointer(P); end // 新页数>原页数,重新申请并Copy原数据到新数据 else if NewN>OldN then begin NewP := VMAlloc(dwSize, False); //原数据Copy到新数据中 if NewP<>nil then CopyMemory(NewP, Pointer(P), OldN*m_PageSize); //放回原页数 VMFree(P, False); //返回 Pointer(P) := NewP; Result := NewP; end; finally LeaveCriticalSection(m_VMLock); end;end;function TVirtualMemPool.VMFree(var P; IsLock: Boolean = True): Boolean;var M, N, NEnd: Cardinal;begin if Pointer(P)=nil then Exit; if IsLock then EnterCriticalSection(m_VMLock); try M := (Cardinal(Pointer(P))-Cardinal(m_lpBase)) div m_PageSize; Pointer(P) := nil; // 页数 N := m_Buckets[M]^.count; NEnd := M + N; // 放回 while M<NEnd do begin m_SBTStorage.add(m_Buckets[M]); Inc(M); end; finally if IsLock then LeaveCriticalSection(m_VMLock); end; Result := True;end;end.用法var VMM: TVirtualMemPool; p: Pointer;begin VMM := TVirtualMemPool.Create(100000); //申请内存 p := VMM.VMAlloc(1024); //重新申请大小 p := VMM.VMReAlloc(1024); //释放内存 VMM.VMFree(p); VMM.Free;end;
具体代码大家可以慢慢看,另请高手看到后不要取笑,希望高手能优化一份并共享出来!
代码里使用的方法基本与linux内存管理原理差不多!可能也与windows内存管理大同小异吧!
不对之处请高手指正
- delphi,IOCP之内存分配池[1]
- IOCP之内存分配池[1]
- C++之内存分配
- C++之内存分配
- java之内存分配
- C++之内存分配
- LDD之内存分配
- CPP之内存分配
- 编程之内存分配问题
- java基础之内存分配
- 杂记之内存分配实例
- linux realloc之内存分配
- 内存管理之内存分配
- JVM之内存区域分配
- jvm之内存分配策略
- C++内存管理之内存分配详解
- C++并不难—之内存分配
- C++之内存分配
- 组件制作之一(概念)
- Index scan for like %%
- OpenCV中FilterEngine与filter、image的关系
- 如何在单个Oracle实例中创建多个Geodatabase
- 备份和还原cacti
- IOCP之内存分配池[1]
- Axis部署开发webservice (三种方式全)
- ICMP协议
- inux添加用户(user)到用户组(group)
- [1] Java类的反射机制
- default关键字作用
- weblogic数据源配置
- svn安装完成check后无法commit错误信息,及相应的解决办法
- Android 软件开发之如何使用Eclipse Debug调试程序详解(十二)