Функции Delphi / SAP OCX / Контроль входа в систему: утечка памяти - PullRequest
0 голосов
/ 29 августа 2011

Я подключаюсь к SAP-серверу через SAP Logon Control TLB (который при первом запуске съедает около 25 МБ памяти !!), а затем запрашиваю некоторые данные.Каждый вызов требует ~ 200 кБ.Поскольку я не хочу переподключаться каждый раз, я сохраняю соединение и передаю его объекту функции SAP каждый раз, когда мне это нужно (кажется, что объект копируется, потому что этот процесс также стоит около 6 МБ).После завершения запросов я освобождаю объект ... но использование памяти не уменьшается?Поэтому, если я позволю программе работать около 4 часов, моя память заполнится, и компьютер выйдет из строя.

код (упрощенный):

connection.pas (создает соединение):

SAPLogonCtrl : TSAPLogonControl;

constructor TCon.Create(usr, pswd, sys, appserv, sysnum, clnt);
begin
    inherited Create;
    SAPLogonCtrl := TSAPLogonControl.Create(nil);
    with SAPLogonCtrl do begin
        User := usr;
        Password := pswd;
        ...
        Client := clnt;
    end;
    FConnection := SAPLogonCtrl.NewConnection;
    FConnection.Logon(0, true);   //<------------- this needs ~25MB
end;

main.pas:

...
procedure TMain.Query;
var
    theQuery : TSomeQuery;
begin
    theQuery := TSomeQuery.Create;
    theQuery.Data1 := 'something gets here';
    theQuery.Data2 := 'here too';
    theQuery.Call;    // <------------------------ this needs about ~100kB
    ...
    theQuery.Free;    // <------------------------ nothing happens here, no mem freed!
end;
...

someQuery.pas (создает объект и вызывает запрос):

var
    mySAPFunction: TSapFunctions;
    mySAPQuery: Variant;

...
procedure Call;
begin
    mySAPFunction := TSAPFunctions.Create;
    mySAPFunction.Connection := FConnection;   // <---- connection is passed (copied? costs about 5MB) from connection.pas
    mySAPFunction.RemoveAll; // removes prevous added interfaces
    mySAPQuery := mySAPFunction.Add('interface here');
    mySAPQuery.Call;
    ...
    // return the result
end;

Надеюсь, это понятно и чтокто-то может помочь мне, потому что с этой утечкой памяти моя программа практически непригодна: (

Заранее спасибо, Eike.

1 Ответ

2 голосов
/ 29 августа 2011

Вы можете принудительно освободить экземпляр варианта интерфейса, установив для него значение nil:

procedure Call;
begin
    mySAPFunction := TSAPFunctions.Create;
    mySAPFunction.Connection := FConnection;   // <---- connection is passed (copied? costs about 5MB) from connection.pas
    mySAPFunction.RemoveAll; // removes prevous added interfaces
    mySAPQuery := mySAPFunction.Add('interface here');
    mySAPQuery.Call;
    mySAPQuery := null; // will release the memory
end;

На самом деле, я думаю, что mySAPQuery должен быть сделан локальным для вашей процедуры вызова: в этом случае mySapQuery := nullзаявление будет сделано компилятором.

...