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 关于字符串, 之前没这样用过

Delphi 保存hotkey1.hotkey值

Delphi关于邮箱收信的问题

Delphi 调用sql和mysql存储过程

Delphi d10.x 在安卓app开发中使用jar包的注意事项

Delphi杀进程的两种方式

Delphi 如何获得其他进程的token

Delphi tbitmap创建时提示object or class type required

winapi 字符及字符串函数(11): lstrcpyn - 复制字符串, 同时指定要复制的长度

Delphi android 拨打电话

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



打赏

取消

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

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

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

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

评论

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