zoukankan      html  css  js  c++  java
  • 内存池

    unit untMemoryPool;

    interface
    {$WARNINGS OFF}
    uses
      System.Classes, System.SysUtils, Winapi.Windows;

    type
      //Node for block memory
      pMemNode = ^TMemNode;
      TMemNode = record
        Free : Boolean;                 //Is free?
        FSize: Integer;                 //Block Size
        FAddr: Pointer;                 //Address pointer to memory allocated

        FNext: pMemNode;                //Next block pointer
        FPrev: pMemNode;                //Block befor
      end;

      //Memory pool class
      TMemoryPool = class(TObject)
      private
        FBlkSize: Integer;               //Block size
        FBlkCnt : Integer;               //Memory bock count each time allocate
        FMemHead: pMemNode;              //Memory list
        FreeHead: pMemNode;              //Free memory start position
        FMemTail: pMemNode;              //Tail of current memory
        FLock   : TRTLCriticalSection;

        procedure InitLock;
        procedure Lock;
        procedure UnLock;
        procedure UnInitLock;

        procedure GetResource(ABlocks: Integer);
        procedure FreeResource;

      public
        constructor Create(const ABlocks: Integer = 10; const ABlockSize: Integer = 1024);
        destructor Destroy; override;

        //Get a free buffer
        function  GetBuffer: Pointer;
        //After use the buffer
        function FreeBuffer(const ABuffer: Pointer): Boolean;

      published
        property BlockSize: Integer read FBlkSize;

      end;

    implementation

    { TMemoryPool }
    {******************************************************************************}
    {*     Procedure: Create                                                      *}
    {*       Purpose: constructor of TMemoryPool.                                 *}
    {*    Paramaters: ABlocks    --  Block to allocate when create.               *}
    {*                ABlockSize --  Each block size.                             *}
    {******************************************************************************}
    constructor TMemoryPool.Create(const ABlocks, ABlockSize: Integer);
    begin
      InitLock;

      FBlkCnt := ABlocks;
      FBlkSize:= ABlockSize;

      FMemHead:= nil;
      FMemTail:= nil;
      FreeHead:= nil;

      GetResource(ABlocks);
    end;

    {******************************************************************************}
    {*     Procedure: Destroy                                                     *}
    {*       Purpose: Destrucotr of TMemoryPool.                                  *}
    {*    Paramaters: None.                                                       *}
    {******************************************************************************}
    destructor TMemoryPool.Destroy;
    begin
      FreeResource;
      UnInitLock;

      inherited;
    end;

    {******************************************************************************}
    {*      Function: FreeBuffer                                                  *}
    {*       Purpose: Free memory buffer allocated.                               *}
    {*    Paramaters: ABuffer  --  Buffer address to free.                        *}
    {*        Return: True  --  Block is free.                                    *}
    {*                False --  Free error or the block not found.                *}
    {******************************************************************************}
    function TMemoryPool.FreeBuffer(const ABuffer: Pointer): Boolean;
    var
      m_pTmp: pMemNode;
    begin
      Result:= false;

      Lock;
      try
        if (nil = ABuffer) then exit;

        m_pTmp:= FMemHead;
        while (m_pTmp <> nil) do
        begin
          if (ABuffer = m_pTmp.FAddr) then
          begin
            if FreeHead = nil then
              FreeHead:= FMemTail
            else
              FreeHead:= FreeHead.FPrev;     //Move free head back

            //Swap two blocks's content
            m_pTmp.Free := false;
            m_pTmp.FAddr:= FreeHead.FAddr;
            FreeHead.Free := true;
            FreeHead.FAddr:= ABuffer;

            Result:= true;
            exit;
          end;
          m_pTmp:= m_pTmp.FNext;

          // Not find the block, exit
          if (m_pTmp = FreeHead) then break;
        end;
      finally
        UnLock;
      end;
    end;

    {******************************************************************************}
    {*     Procedure: FreeResource                                                *}
    {*       Purpose: Free all memory allocated.                                  *}
    {*    Paramaters: None.                                                       *}
    {******************************************************************************}
    procedure TMemoryPool.FreeResource;
    var
      m_pNode: pMemNode;
      m_pTmp : pMemNode;
    begin
      m_pNode:= FMemHead;

      try
        while (m_pNode <> nil) do
        begin
          m_pTmp:= m_pNode;
          m_pNode:= m_pNode.FNext;

          FreeMem(m_pTmp.FAddr);
          Dispose(m_pTmp);
        end;
      except
      end;

      FMemHead:= nil;
    end;

    {******************************************************************************}
    {*      Function: GetBuffer                                                   *}
    {*       Purpose: Get a memroy block buffer.                                  *}
    {*    Paramaters: None.                                                       *}
    {*        Return: Pointer  --  A pointer pointer to buffer.                   *}
    {******************************************************************************}
    function TMemoryPool.GetBuffer: Pointer;
    begin
      Lock;
      try
        //If there's no free memroy, allocate new memory
        if (FreeHead = nil) then
          GetResource(FBlkCnt);

        //Return free memory head address
        Result:= FreeHead.FAddr;
        //Mark the block is not free
        FreeHead.Free:= false;
        //Move free head pointer forward
        FreeHead:= FreeHead.FNext;
      finally
        UnLock;
      end;
    end;

    {******************************************************************************}
    {*     Procedure: GetResource                                                 *}
    {*       Purpose: Allocate memroy.                                            *}
    {*    Paramaters: ABlocks  --  How many blocks to allocate.                   *}
    {******************************************************************************}
    procedure TMemoryPool.GetResource(ABlocks: Integer);
    var
      m_pNode: pMemNode;
      m_iTmp : Integer;
    begin
      if (ABlocks <= 0) or (FBlkSize <= 0) then exit;

      //Get new memory block
      new(m_pNode);
      m_pNode.Free := true;
      m_pNode.FSize:= FBlkSize;
      m_pNode.FPrev:= FMemTail;
      GetMem(m_pNode.FAddr, FBlkSize);
      m_pNode.FNext:= nil;

      //If the memroy block list is empty, assign head
      if FMemHead = nil then
      begin
        FMemHead:= m_pNode;
        FMemTail:= FMemHead;
        FreeHead:= FMemHead;
      end
      else begin
        FMemTail.FNext:= m_pNode;
        FMemTail:= m_pNode;
      end;

      if (FreeHead = nil) then
        FreeHead:= m_pNode;

      for m_iTmp:= 1 to ABlocks - 1 do
      begin
        new(m_pNode);
        m_pNode.Free := true;
        m_pNode.FSize:= FBlkSize;
        m_pNode.FNext:= nil;
        m_pNode.FPrev:= FMemTail;
        GetMem(m_pNode.FAddr, FBlkSize);

        FMemTail.FNext:= m_pNode;
        FMemTail:= m_pNode;
      end;
    end;

    procedure TMemoryPool.InitLock;
    begin
      InitializeCriticalSection(FLock);
    end;

    procedure TMemoryPool.Lock;
    begin
      EnterCriticalSection(FLock);
    end;

    procedure TMemoryPool.UnInitLock;
    begin
      DeleteCriticalSection(FLock);
    end;

    procedure TMemoryPool.UnLock;
    begin
      LeaveCriticalSection(FLock);
    end;

    end.

  • 相关阅读:
    微信小程序 获取手机号 获取基础信息 自定义分享 获取dom节点
    微信公众号 生成带参数进入公众号关注页的二维码 监听用户关注公众号事件 自定义菜单栏 (服务端)
    js 防抖和节流 (学习笔记)
    vue 封装axios api模块化 并使用方式 MD5 数据加密
    1.1 Logistics Regression模型
    音视频入门-19-使用giflib处理GIF图片
    思维
    面试题库
    前端代码规范
    D3JS笔记
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2512943.html
Copyright © 2011-2022 走看看