gpt4 book ai didi

Delphi DataSnap函数返回TStream和内存泄漏

转载 作者:行者123 更新时间:2023-12-02 02:27:18 24 4
gpt4 key购买 nike

我正在使用基本的 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 会小心释放它,否则我会遇到内存泄漏问题?

最佳答案

我做了一个实验来研究这个问题,结果令我惊讶。

让 DataSnapServer 向导(在文件 | 新建 | 其他 | Delphi 项目 | 下)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;

,编译,在TMyStringStream.Destroy中的Clear上打断点,然后运行。

然后,创建/运行一个最小的客户端,它会执行类似的操作

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;

如果您随后在客户端中单击 Button2,您会发现服务器停止在TMyStringStream.Destroy 中的断点。这是 FreeAndNil(FAlulatedReturn) 的结果在 block 中执行

  if not FServerSideCommand then
try
FreeAndNil(FAllocatedReturn)
except
Result := false
end;

在 DataSnap.DSReflect 中的函数 TDSMethodValues.ClearReferenceParameters: boolean 中。

所以它看起来像一个在您的服务器方法中分配并分配给的 Stream它的 Result 将被释放(无论您是否喜欢),这样就不会泄漏。但我认为您应该将其视为一般规则的一个狭隘异常(exception),即如果您通过局部变量创建 Delphi 对象,则应该在变量超出范围之前将其释放。

关于Delphi DataSnap函数返回TStream和内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40954982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com