1. 程式人生 > >Delphi 的TStringBuilder防止服務器內存碎片化

Delphi 的TStringBuilder防止服務器內存碎片化

防止 size span 內存空間 .get cte protect int eof

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.

Delphi 的TStringBuilder防止服務器內存碎片化