Delphi 的TStringBuilder防止服务器内存碎片化


本文整理自网络,侵删。

 
Delphi 2009+ 的 System.SysUtils提供了一个类似.Net的StringBuilder,用于存储字符数组。

很多人不明白为什么要用TStringBuilder, Delphi中有string,有几乎所有TStringBuilder的功能函数, System.SysUtils中还有TStringHelper方便扩展String,更方便String的使用。

从Delphi提供的源码看,TStringBuilder与string最大的区别是,TStringBuilder是可以预先申请了内存空间,并限制最大内存空间,不会自动释放,而string是用多少申请多少内存,自动释放。

由此可见TStringBuilder相对于String的优势有2:

1.在开发服务器软件时,使用TStringBuilder池,可以有效地防止内存碎片化.

2.由于不需要开辟新的存储空间存储更大的字符串,预先申请内存的TStringBuilder的运行效率将超越string.

下面的代码中TServerString继承自TStringBuilder,内存空间限制大小为MaxMemorySize,, 当准备写入的字符将要超过内存大小时,将自动抛出异常,

服务器软件可以接获此异常后处理。

下面的代码有待测试:

unit Iocp.ServerString;

interface

uses SysUtils, Classes;

type
  TServerStringPool=class;
  TServerString=class(TStringBuilder)
  protected
    class var FPool:TServerStringPool;
    constructor Create;
  public
    destructor Destroy;override;
  end;

  TServerStringPool=class
  protected
    FList:TThreadList;
  public
    constructor Create(Capacity:Integer);
    destructor Destroy;override;
    function GetString:TServerString;
    procedure FreeString(Value:TServerString);
  end;

implementation

const
  MaxMemorySize=16384;


{ TServerString }

constructor TServerString.Create;
var
  N:Integer;
begin
  N:=(MaxMemorySize-InstanceSize) div SizeOf(Char);
  inherited Create(N, N);
end;

destructor TServerString.Destroy;
begin
  FPool.FreeString(Self);
end;

{ TServerStringPool }

constructor TServerStringPool.Create(Capacity: Integer);
var
  i: Integer;
  L:TList;
begin
  inherited Create;
  L:=FList.LockList;
  try
    for i := 1 to Capacity do
    begin
      L.Add(TServerString.Create);
    end;
  finally
    FList.UnlockList;
  end;
end;

destructor TServerStringPool.Destroy;
var
  i: Integer;
  L:TList;
begin
  L:=FList.LockList;
  try
    for i := L.Count-1 to 0 do
      TStringBuilder(L[i]).Free;
  finally
    FList.UnLockList;
  end;
  FList.Free;
  inherited;
end;

procedure TServerStringPool.FreeString(Value: TServerString);
begin
  FList.Add(Value);
end;

function TServerStringPool.GetString: TServerString;
var
  L:TList;
begin
  L:=FList.LockList;
  try
    if L.Count=0 then
    begin
      Result:=TServerString.Create;
    end
    else
    begin
      Result:=TServerString(L[L.Count-1]);
      L.Delete(L.Count-1);
    end;
  finally
    FList.UnlockList;
  end;
end;

initialization
  TServerString.FPool:=TServerStringPool.Create(10240);
finalization
  TServerString.FPool.Free;
end.

来源:https://www.cnblogs.com/hezihang/p/3321647.html

相关阅读 >>

Delphi d10.x 安卓app开发中创建密钥库文件

Delphi access 从数据库里随机选择一行

Delphi firemonkey应用程序中显示时隐藏虚拟键盘

Delphi fdmemtable1内存表字段排序

Delphi xe5 android openurl

Delphi 10.4 新变化:定制拖管记录(结构)类型

Delphi 2009 的反射单元(objauto):

Delphi 字符串加密解密单元

Delphi 删除memo某一行

Delphi 快速删除非空文件夹

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...