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,, 当准备写入的字符将要超过内存大小时,将自动抛出异常,

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

下面的代码有待测试:

 

  1 unit Iocp.ServerString;
  2 
  3 interface
  4 
  5 uses SysUtils, Classes;
  6 
  7 type
  8   TServerStringPool=class;
  9   TServerString=class(TStringBuilder)
 10   protected
 11     class var FPool:TServerStringPool;
 12     constructor Create;
 13   public
 14     destructor Destroy;override;
 15   end;
 16 
 17   TServerStringPool=class
 18   protected
 19     FList:TThreadList;
 20   public
 21     constructor Create(Capacity:Integer);
 22     destructor Destroy;override;
 23     function GetString:TServerString;
 24     procedure FreeString(Value:TServerString);
 25   end;
 26 
 27 implementation
 28 
 29 const
 30   MaxMemorySize=16384;
 31 
 32 
 33 { TServerString }
 34 
 35 constructor TServerString.Create;
 36 var
 37   N:Integer;
 38 begin
 39   N:=(MaxMemorySize-InstanceSize) div SizeOf(Char);
 40   inherited Create(N, N);
 41 end;
 42 
 43 destructor TServerString.Destroy;
 44 begin
 45   FPool.FreeString(Self);
 46 end;
 47 
 48 { TServerStringPool }
 49 
 50 constructor TServerStringPool.Create(Capacity: Integer);
 51 var
 52   i: Integer;
 53   L:TList;
 54 begin
 55   inherited Create;
 56   L:=FList.LockList;
 57   try
 58     for i := 1 to Capacity do
 59     begin
 60       L.Add(TServerString.Create);
 61     end;
 62   finally
 63     FList.UnlockList;
 64   end;
 65 end;
 66 
 67 destructor TServerStringPool.Destroy;
 68 var
 69   i: Integer;
 70   L:TList;
 71 begin
 72   L:=FList.LockList;
 73   try
 74     for i := L.Count-1 to 0 do
 75       TStringBuilder(L[i]).Free;
 76   finally
 77     FList.UnLockList;
 78   end;
 79   FList.Free;
 80   inherited;
 81 end;
 82 
 83 procedure TServerStringPool.FreeString(Value: TServerString);
 84 begin
 85   FList.Add(Value);
 86 end;
 87 
 88 function TServerStringPool.GetString: TServerString;
 89 var
 90   L:TList;
 91 begin
 92   L:=FList.LockList;
 93   try
 94     if L.Count=0 then
 95     begin
 96       Result:=TServerString.Create;
 97     end
 98     else
 99     begin
100       Result:=TServerString(L[L.Count-1]);
101       L.Delete(L.Count-1);
102     end;
103   finally
104     FList.UnlockList;
105   end;
106 end;
107 
108 initialization
109   TServerString.FPool:=TServerStringPool.Create(10240);
110 finalization
111   TServerString.FPool.Free;
112 end.

 

 

 

 

 

posted @ 2013-09-14 19:24  子航  阅读(1971)  评论(1编辑  收藏  举报