我正在使用基本的DataSnap服务器。 我正在使用XE8,Windows 8.1
我有下一个服务器功能:
function TSrvServerMetodos.ImagePac(pront:integer): TStream;
var blob:TStream;
strm:TMemoryStream;
begin
with qrytemp do begin
Params.Clear;
SQL.Clear;
SQL.Add('SELECT F.PICTURE FROM CLIENTES F WHERE F.PRONT=:pront');
UnPrepare;
Prepare;
Params[0].Value:=pront;
Open;
if IsEmpty then result:=nil
else begin
try
Result := CreateBlobStream(fieldbyname('pict'),bmRead);
GetInvocationMetadata.ResponseContentType := 'image/jpeg';
except
Result:=nil
end;
end;
end;
end;
我的客户端应用是Android应用。一切运作良好,我可以得到结论。
我怀疑Datasnap服务器上的内存泄漏。
由于结果是我创建的TStream,Datasnap Server会小心释放它,否则我会遇到内存泄漏问题?
答案 0 :(得分:4)
我做了一个实验来研究这个,结果让我感到惊讶。
让DataSnapServer向导(在File | New | Other | Delphi Projects |。下) DataSnap Server)创建一个默认服务器项目,然后进行以下添加
type
TMyStringStream = class(TStringStream)
public
constructor Create(Value : String);
destructor Destroy; override;
end;
TServerMethods1 = class(TDSServerModule)
[...]
function TServerMethods1.GetStream(Value: String): TStream;
var
SS : TMyStringStream;
begin
SS := TMyStringStream.Create(Value);
SS.Position := 0;
Result := SS;
end;
constructor TMyStringStream.Create(Value: String);
begin
inherited Create;
WriteString(Value);
end;
destructor TMyStringStream.Destroy;
begin
Clear;
inherited;
end;
,编译,在Clear
的{{1}}上放置一个断点并运行。
然后,创建/运行一个像这样做
的最小客户端TMyStringStream.Destroy
如果您随后在客户端中单击Button2,您将发现服务器已停止
procedure TDSClientForm.Button2Click(Sender: TObject);
var
SS : TStringStream;
S : TStream;
begin
SqlServerMethod2.Params[0].AsString := 'ABC123';
SqlServerMethod2.ExecuteMethod;
SS := TStringStream.Create;
try
S := SqlServerMethod2.Params[1].AsStream; //, 6{SqlServerMethod2.Params[1].Size});
S.Position := 0;
SS.CopyFrom(S, S.Size);
ShowMessage(SS.DataString);
finally
SS.Free;
end;
end;
中的断点。这是TMyStringStream.Destroy
的结果
在块中执行
FreeAndNil(FAllocatedReturn)
在DataSnap.DSReflect中的 if not FServerSideCommand then
try
FreeAndNil(FAllocatedReturn)
except
Result := false
end;
。
因此它看起来像是在您的服务器方法中分配的流并被分配给 它的结果将被释放(无论你喜不喜欢),这样就不会泄漏。但我认为你应该认为这是一般规则的一个狭隘的例外,如果你通过局部变量创建一个Delphi对象,你应该在变量超出范围之前处理它。