• RTL底层释放或回收对象


    对象实例数据链表结构

    PObjectInstance = ^TObjectInstance;
    TObjectInstance = packed record
    Code: Byte;
    Offset: Integer;
    case Integer of
    0: (Next: PObjectInstance);
    1: (FMethod: TMethod);
    end;

    对象实体块链表结构

    `PInstanceBlock = ^TInstanceBlock;`
    `TInstanceBlock = packed record`
    `Next: PInstanceBlock;`
    `Code: array[1..CodeBytes] of Byte;`
    `WndProcPtr: Pointer;` // 窗口回调处理过程指针
    `Instances: array[0..InstanceCount] of TObjectInstance;` //实体对象数组
    

    end;

    var
    (* 运行程序所占内存块链表的首地址 *)
    InstBlockList: PInstanceBlock;
    (* InstFreeList指向空闲对象实例链表的首地址 *)
    InstFreeList: PObjectInstance;

    // 为对象分配内存空间,并指定回调方法(代码区)
    function MakeObjectInstance(const AMethod: TWndMethod): Pointer;
    const
    BlockCode: array[1..CodeBytes] of Byte = (
    {$IF Defined(CPUX86)}
    $59, { POP ECX }
    $E9); { JMP StdWndProc }
    {$ELSEIF Defined(CPUX64)}
    $41,$5b, { POP R11 }
    $FF,$25,$00,$00,$00,$00); { JMP [RIP+0] }
    {$ENDIF}
    PageSize = 4096;
    var
    Block: PInstanceBlock;
    Instance: PObjectInstance;
    begin
    if InstFreeList = nil then
    begin
    Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    Block^.Next := InstBlockList;
    Move(BlockCode, Block^.Code, SizeOf(BlockCode));
    {$IF Defined(CPUX86)}
    Block^.WndProcPtr := Pointer(CalcJmpOffset(@Block^.Code[2], @StdWndProc));
    {$ELSEIF Defined(CPUX64)}
    Block^.WndProcPtr := @StdWndProc;
    {$ENDIF}
    Instance := @Block^.Instances;
    repeat
    Instance^.Code := $E8; { CALL NEAR PTR Offset }
    Instance^.Offset := CalcJmpOffset(Instance, @Block^.Code);
    Instance^.Next := InstFreeList;
    InstFreeList := Instance;
    Inc(PByte(Instance), SizeOf(TObjectInstance));
    until IntPtr(Instance) - IntPtr(Block) >= SizeOf(TInstanceBlock);
    InstBlockList := Block;
    end;
    Result := InstFreeList;
    Instance := InstFreeList;
    InstFreeList := Instance^.Next;
    Instance^.FMethod := TMethod(AMethod);
    end;

    //回收空闲的对象
    procedure FreeObjectInstance(ObjectInstance: Pointer);
    begin
    if ObjectInstance <> nil then
    begin
    // 将需要释放的对象ObjectInstance掺入链表首部
    PObjectInstance(ObjectInstance)^.Next := InstFreeList;
    InstFreeList := ObjectInstance;
    end;
    `end;

  • 相关阅读:
    Vue3.0版本以上路由跳转控制台报错调整
    vue-cli3.0 项目如何使用sass less
    vue-element-admin项目npm install 安装不成功问题
    封装axios
    element ui判断是否必填添加校验
    element ui上传图片限制尺寸(宽、高、)大小、格式等
    阿里云服务器挂载新数据盘
    GitHub上最火的40个Android开源项目
    设计模式——设计原则
    设计模式——策略模式
  • 原文地址:https://www.cnblogs.com/windlog/p/12350266.html
Copyright © 2020-2023  润新知