2011-08-29 48 views
0

我通过SAP Logon Control TLB(首次启动时消耗大约25MB的内存!!)连接到SAP服务器,然后查询一些数据。每个呼叫需要〜200 kB。因为我不想每次都重新连接,所以每次需要时我都会存储连接并将其传递给SAP函数对象(似乎该对象被复制,因为此proc的成本大约为6MB)。在完成查询后,我释放了该对象......但内存使用情况并未下降?因此,如果我让程序运行了大约4个小时,我的内存已满,电脑崩溃。Delphi/SAP函数OCX /登录控制:内存泄漏

代码(简化):

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。

+0

东西是不正确的......你定义“myQuery:Variant”;然后使用“mySAPQuery” – ComputerSaysNo

+0

谢谢,编辑 –

回答

2

您可以强制通过将其设定释放变种接口实例为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说明会由编译器制作。

+0

将它设置为零会产生一个错误:不兼容的类型:'Variant'和'指针'。你的意思是来自变体单元的空值? –

+0

是的。我在SO中写了这个。并在IInterface和Variant之间混淆了一下。 ;) –