Delphi 的TStringBuilder防止服務器內存碎片化
阿新 • • 發佈:2017-05-15
防止 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防止服務器內存碎片化