首页 > 系统相关 >内存池

内存池

时间:2023-06-18 10:24:33浏览次数:32  
标签:begin end FList TMemPool 内存 procedure size

内存池

/// <author>cxg 2020-9-8</author>
/// 支持D7,更低版本没有测试,支持跨OS
unit MemPool;

interface

uses
  Math, Classes, SysUtils, SyncObjs;

type
  {$if CompilerVersion < 18} //before delphi 2007
  TBytes = array of Byte;
  {$ifend}
  TMemBlock = record
    buf: Pointer;
    size: Cardinal;
  end;

  pMemBlock = ^TMemBlock;

  TMemPool = class
  private
    FList: TList;
    FBlockSize: Cardinal;
    FCS: TCriticalSection;
  private
    procedure Lock;
    procedure UnLock;
    procedure newBlocks(const BlockNum, blockSize: Cardinal);
  public
    constructor Create(const blockNum: Cardinal; const blockSize: Cardinal);
    destructor Destroy; override;
  public
    function GetBlock: Pointer;
    procedure backBlock(const block: Pointer);
  end;

type
  TMemList = class
  private
    FPool: TMemPool;
    FList: TList;
  private
    function GetSize: Int64;
  public
    constructor Create(pool: TMemPool);
    destructor Destroy; override;
  public
    procedure addBuf(const buf: Pointer; const len: Cardinal);
    procedure backList;
    procedure fromStream(ms: TMemoryStream);
    procedure toStream(ms: TMemoryStream);
    function toBytes: tbytes;
    function toBuf: Pointer;
  public
    property list: TList read FList;
    property size: Int64 read GetSize;
  end;

implementation

{ TMemPool }
constructor TMemPool.Create(const BlockNum, BlockSize: Cardinal);
begin
  FCS := TCriticalSection.Create;
  FList := TList.Create;
  FBlockSize := BlockSize;
  newBlocks(BlockNum, FBlockSize);
end;

destructor TMemPool.Destroy;
begin
  FreeAndNil(FList);
  FreeAndNil(FCS);
  inherited;
end;

procedure TMemPool.backBlock(const block: Pointer);
begin
  Lock;
  try
    FList.Add(block);
  finally
    UnLock;
  end;
end;

function TMemPool.GetBlock: Pointer;
begin
  Lock;
  try
    if FList.Count = 0 then
      newBlocks(1, FBlockSize);
    Result := FList.Last;
    FList.Delete(FList.Count - 1);
  finally
    UnLock;
  end;
end;

procedure TMemPool.newBlocks(const BlockNum, blockSize: Cardinal);
var
  i: Integer;
  p: pMemBlock;
begin
  for i := 1 to BlockNum do
  begin
    New(p);
    GetMem(p.buf, BlockSize);
    FList.Add(p);
  end;
end;

procedure TMemPool.Lock;
begin
  FCS.Enter;
end;

procedure TMemPool.UnLock;
begin
  FCS.Leave;
end;

{ TMemList }

procedure TMemList.addBuf(const buf: Pointer; const len: Cardinal);
var
  p: pMemBlock;
begin
  p := FPool.GetBlock;
  p.buf := buf;
  p.size := len;
  FList.Add(p);
end;

constructor TMemList.Create(pool: TMemPool);
begin
  FPool := pool;
  FList := TList.Create;
end;

destructor TMemList.Destroy;
begin
  FreeAndNil(FList);
  inherited;
end;

procedure TMemList.backList;
var
  p: pMemBlock;
  i: integer;
begin
  for i := flist.Count - 1 downto 0 do
  begin
    p := pmemblock(flist[i]);
    FPool.backBlock(p);
    flist.Delete(i);
  end;
end;

function TMemList.GetSize: Int64;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to FList.Count - 1 do
    Result := Result + pmemblock(FList[i]).size;
  //i := FList.Count;
 // Result := FPool.FBlockSize * (i - 1) + pMemblock(FList[i - 1]).size;
end;

function TMemList.toBuf: Pointer;
var
  i: integer;
  p: pMemBlock;
begin
  New(Result);
  GetMem(Result, self.getsize);
  for i := 0 to flist.Count - 1 do
  begin
    p := pmemblock(list[i]);
    Move(p.buf^, Result^, p.size);
    if i < flist.Count - 1 then
      Result := Pointer(Cardinal(Result) + p.size);
  end;
end;

function TMemList.toBytes: tbytes;
var
  i: integer;
  p: pMemBlock;
begin
  SetLength(result, self.GetSize);
  for i := 0 to flist.Count - 1 do
  begin
    p := pmemblock(list[i]);
    Move(p.buf^, Result[i * p.size], p.size);
  end;
end;

procedure TMemList.toStream(ms: TMemoryStream);
var
  i: integer;
  p: pMemBlock;
begin
  ms.SetSize(Self.GetSize);
  for i := 0 to flist.Count - 1 do
  begin
    p := pmemblock(list[i]);
    ms.Write(p.buf^, p.size);
  end;
end;

procedure TMemList.fromStream(ms: TMemoryStream);
var
  p: pMemBlock;
  qty, remain, n, i: Integer;
begin
  backList;
  qty := Ceil(ms.Size / FPool.FBlockSize);
  n := qty - 1;
  remain := ms.Size - (n * FPool.FBlockSize);
  for i := 1 to qty do
  begin
    p := FPool.GetBlock;
    if i = qty then
    begin
      ms.Read(p.buf, remain);
      p.size := remain;
    end
    else
    begin
      ms.Read(p.buf, FPool.FBlockSize);
      p.size := FPool.FBlockSize;
    end;
    flist.Add(p);
  end;
end;

end.

  

标签:begin,end,FList,TMemPool,内存,procedure,size
From: https://www.cnblogs.com/hnxxcxg/p/17488766.html

相关文章

  • VisualVM 2.1.6 工具监控、查看内存溢出的jar服务包
    VisualVM2.1.6    链接:https://pan.baidu.com/s/1h_qacWhaQrW9kA97wdMnJQ提取码:ey5b  JTop.jar  存放路径:C:\ProgramFiles\Java\jdk-11.0.17\demo\management\JTop链接:https://pan.baidu.com/s/1UOE3ECl0-KqXnOFxs-Criw提取码:daL9 使用步骤:Visual......
  • OOM看 之 低端内存保护机制lowmem_reserve
    一什么是lowmem_reserve为了防止高端内存申请者”偷用”太多的低端内存,内核的内存页分配器提供了一种叫做”lowmem_reserve”的机制防止来防止高端内存的申请者占用太多低端内存,这个机制是通过”lowmem_reserve_ratio”这个调节接口来决定低端内存被高端内存占用的程度。lowmem......
  • 腾讯太狠:40亿QQ号, 给你1G内存,怎么去重?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • 申请可执行内存
    #include<winhvplatform.h>#include<memoryapi.h>add(inta,intb){returna+b;}硬编码unsignedcharcode[]={0x55,0x48,0x89,0xe5,0x89,0x4d,0x10,0x89,0x55,0x18,0x8b,0x55,0x10,0x8b,0x......
  • 服务器内存跑满是什么原因造成的 43.248.101.x
    相信大家在使用服务器的时候会有出现内存使用率比较高的情况,那接下来小编跟大家说下到底是哪些原因导致内存不足:一、应用程序池应用程序池有一个默认回收的时间,到了这个时间就会自动释放内存,这个时间一般是1740分钟,而这种程度的时间可能会导致应用程序池无法及时释放内存,从而出现内......
  • VMIC5565反射内存卡供应厂家 PCI-5565多模光钎网络 GE反射内存模块 VMIC反射内存PMC系
    反射内存实时网的特点VMIC反射内存是一种通过局域网在互连的计算机间提供的数据传输的技术,强实时网络设计人员已经越来越多地采用这种技术。VMIC反射内存实时局域网的概念十分简单,就是设计一种网络内存板,在分布系统中实现内存至内存的通信,并且没有软件开销。每台结点机上插一块反射......
  • RK3588(YD-88)瑞芯微 Rockchip RK3588 开发板套件,支持8G内存,32G eMMC存储
     一、产品简介1.产品简述:YD-88 是基于瑞芯微RK3588 的一款核心板RK3588是一颗高性能、低功耗的应用处理器芯片,专为ARMPC、边缘计算、个人移动互联网设备和其它多媒体应用而设计,是由4个A76和4个A55与独立的NEON协处理器集成的。RK3588内置了多种功能强大的嵌入式......
  • Q:Win10关闭内存压缩功能
    微软在Win10中就已经启用了内存压缩机制,在Win11当中继续了这一设定。通过任务管理器查看。taskmgr·通过命令行查看。使用系统管理员权限,打开PowerShell,然后输入以下命令:Get-MMAgent关闭压缩命令:Disable-MMAgent-mc启动压缩命令:Enable-MMAgent-mc......
  • windows虚拟内存
    现象:一个项目上,用户提供的服务器,其初始的C盘占用很大,占用大约90G,而进入C盘全选文件查看大小才大约27G,丢了60多G。 百度查找原因:虚拟内存(也称为页面文件)是一种Windows操作系统用于管理内存的机制。当Windows操作系统已经使用了所有的RAM(物理内存)时,它会动态地将一部分数据(如正......
  • 善待内存
    背景介绍现在有35块内存,每块200M,均采用malloc分配。在使用中,他们都被填入了10M~100M不等的数据,余下部分空闲。然后我们将这35块内存中的有数据部分复制到一块1G的大内存中(已知有效数据总和不超过1G)。 伪代码如下 #defineMAX_PER_BLOCK_MEM_SIZE(1024*1024*200)#defineM......