本人进行一个远程监控编程,出现内存泄漏。
本想自己调试解决,奈于Delphi调试经常死机(这个问题挺怪的,只要关闭delphi32.exe这个程序就什么问题都没有了(可惜这时电脑慢得像蜗牛,只有慢慢等才能关闭delphi32.exe程序))—为什么会这样谁能告诉我??本程序使用Indy组件,整个程序也使用DynamicSkinForm.v5.90.FS.D567皮肤控件。
服务端使用TIdTCPClient,反弹连接。
客户端(也就是管理端)使用TIdTCPServer.
下面这个是程序是放在TidTcpServer.OnExecute中执行,这个过程反复读取服务端发来的图片。我们知道OnExecute事件是线程执行的,如果我把它放到主线程中执行则不会出现内存泄漏,但我的目标是多线程执行,不能放到主线程中,这些现象是不是说明出现程序设计结构错误,又如何解决呢???
procedure ProcessScreenTransfer2(AThread: TIdPeerThread);
var
  ActClient: Ponlineinf;  TheSize:Integer;  Firscr:bool;
  MyTempBmp: TMemoryStream;
  Output:TBitmap;
  iCount,iCount2:integer;
  MyFirstBmp:TBitmap;
begin  ActClient := Ponlineinf(AThread.Data);  AThread.Connection.Tag := 2;
  ActClient^.Tag:=2;  TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).ScreenCThread:=AThread;
  HgzVip.AddLineStr(AThread,HgzVip.Translate('ZhuanTai143','捕获屏幕 - 线路连接成功!'), 1, True);  //初始化变量
  MyTempBmp:= TMemoryStream.Create;
  Output:=nil;
  MyFirstBmp:=nil;
  iCount:=0;
  iCount2:=0;
  Firscr:=True;
  //=======end==============  try
    //读取进度事件过程
    AThread.Connection.OnWork := TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).ShowPicWork;
    AThread.Connection.OnWorkBegin := TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).ShowPicWorkBegin;
    AThread.Connection.OnWorkEnd := TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).ShowPicWorkEnd;
    //==============    //循环读取
    while True do
    begin
      TheSize :=AThread.Connection.ReadInteger; //要下载文件的大小      //TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm)是显示图片的窗体

      TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).Caption :='[' + Ponlineinf(ActClient.Mainthread.Data).ServerName + ']' + HgzVip.Translate('ZhuanTai144','图像大小:')+inttostr(TheSize);      MyTempBmp.Clear;      if Thesize>0 then
      begin          //======读取============
          try
            AThread.Connection.ReadStream(MyTempBmp, TheSize, False); //接收文件
          except
            HgzVip.AddLineStr(ActClient.Mainthread,'接受文件错误!', 1, True);
            if (AThread.Terminated=False) or (AThread.Connection.Connected=False) then
              begin
                Ponlineinf(ActClient.Mainthread.Data).isBpok :=False;
                MyTempBmp.Free;
                Exit;
              end;          end;
          //======end===============
          MyTempBmp.Position:=0;          UnCompressBitmap2(MyTempBmp,Output); //解压
          if not Assigned(Myfirstbmp) then
          begin
            Myfirstbmp:=TBitmap.Create;
            //保存第一张图片
            Myfirstbmp.Assign(Output);
          end else begin            //与第一张图片异或还原原来样子
            RestoreScreen(Myfirstbmp,Output);          end;
          Inc(iCount);          //显示
          TShowPm(Ponlineinf(ActClient.Mainthread.Data).ScreenForm).FDoubleBuffer.Assign(Output);
          FreeAndNil(Output);
          Ponlineinf(ActClient.Mainthread.Data).pData:=Ponlineinf(ActClient.Mainthread.Data).ScreenForm;
          Asynchronous(ActClient.Mainthread,HgzVip.DisplayScreen);          if Ponlineinf(ActClient.Mainthread.Data).ScreenStop then
          begin
            AThread.Connection.Write('000'+EOL); //停止监控
            Break;
          end else begin
            AThread.Connection.Write('111'+EOL); //叫服务器发送下一张图片
          end;      end;    end;    if Assigned(Output) then
      Output.Free;    MyFirstBmp.Free;
    MyTempBmp.Free;    AThread.Connection.Disconnect;
    Ponlineinf(ActClient.Mainthread.Data).ThreadExit:=true;
    Ponlineinf(ActClient.Mainthread.Data).ScreenForm:=nil;  except
    on e:Exception do
    begin
      Ponlineinf(ActClient.Mainthread.Data).ThreadExit:=true;
      Ponlineinf(ActClient.Mainthread.Data).ScreenForm:=nil;
      HgzVip.AddLineStr(ActClient.Mainthread,'错误:' + e.Message, 1, True);    end;  end;
end;本程序也使用FastMM4,能否通过FastMM找到内存泄漏在哪呢??