procedure TThreadResoveData.Execute;
var
  DLLHandle :THandle;
begin
   while not Terminated do
   begin
     Try
       DLLHandle :=LoadLibrary(PChar('MODBUS.dll'));
     Finally
       FreeLibrary(DLLHandle);
     end;
   end;
end;w为啥这内存哗哗的往下跑啊,俺在dll里啥也没做,就这样了,该怎么处理呀,是不是多次调用而没有释放完全呀,有哪位高人遇到过吗?

解决方案 »

  1.   

    没遇到过,你用专门查泄漏的工具试试,memproof
      

  2.   

    LoadLibrary至少不应该在while循环中执行吧。
      

  3.   

    关注放在 while里,可能是为了使内存变化现象更明显吧
      

  4.   


    可能是dll 自己维护着点什么吧。
      

  5.   

    //step1
    procedure TThreadResoveData.Execute;
    var
      DLLHandle :THandle;
    begin
      while not Terminated do
      begin
        DLLHandle :=LoadLibrary(PChar('midas.dll'));
        try
          ReturnValue := 10;
        finally
          FreeLibrary(DLLHandle);
          DLLHandle := 0;
        end;
        Sleep(10); //加入这个延时,继续增加。
      end;
    end;//step2:
    手工调试,在 LoadLibrary(PChar('midas.dll')); 内存增加,在 FreeLibrary(DLLHandle);处内存减少。结果内存无变化。//step3:
    procedure TThreadResoveData.Execute;
    var
      DLLHandle :THandle;
    begin
      while not Terminated do
      begin
        DLLHandle :=LoadLibrary(PChar('midas.dll'));
        try
          ReturnValue := 10;
        finally
          FreeLibrary(DLLHandle);
          DLLHandle := 0;
        end;
        Sleep(1000); //加入这个延时,没有继续增加。
      end;
    end;结论: 释放内存需要时间的。
      

  6.   

    我好像在哪里见过这样的说法。
    LoadLibrary
    其实MS做了一些手法的。并不是立马就真的“Load”,是在合适的时候才“Load”。
    大概的意思是,这里会有个Delay。
    所以,我想的是,这个 API 并不像我们自己写的 exports dll 那么直白。更加像是个 COM 函数。另,线程中,应该sleep一下,哪怕是sleep(0)也是有意义的,表示放出时间片给主线程。lz 不应该这样试验代码。就一段最简单的动态加载。然后用内存检验工具看一下。比如:AQTime 之类的。
    比较好。谁的程序不泄露? 用 FastMM 看一下吧,但凡是 D 写的,多少都有那么几个的。这是没有办法的事情。
    多数原因都是“用空间换时间”造成的。
    能容忍的话,就当没看见好了。
      

  7.   

    不应该是dll的问题,即使你反复loadlibrary,只会存在一份镜像...
      

  8.   

    测试了一下,确实内存占用会不断增加。但在停止该线程后,用getModuleHandle检测dll是否在进程空间内,返回的句柄是0,说明该dll已经被卸载了。
    所以,应该是其它地方引起的内存泄漏,真相不明...
      

  9.   

    只load不free就好了,程序结束的时候,会自动free掉,只能这么干了,实在想不出法子来,反正多次load也是只load了一次
      

  10.   

    在主线程中放个时钟,结果也是这样的:
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
      DLLHandle :THandle;
      ReturnValue: integer;
    begin
      DLLHandle :=LoadLibrary(PChar('midas.dll'));
      try
        ReturnValue := 10;
      finally
        FreeLibrary(DLLHandle);
      end;
    end;
      

  11.   

    VC6代码:
    void CTimerDlg::OnButton1() 
    {
    ::SetTimer(this->m_hWnd, 1, 100, NULL);

    }void CTimerDlg::OnButton2() 
    {
    ::KillTimer(this->m_hWnd, 1);
    }void CTimerDlg::OnTimer(UINT nIDEvent) 
    {
    // TODO: Add your message handler code here and/or call default
        HMODULE h = LoadLibrary("midas.dll");
        FreeLibrary(h); CDialog::OnTimer(nIDEvent);
    }结果相同。
    个人结论:不是DELPHI的线程类的问题,也不是IDE的问题。
      

  12.   

    由15楼想到的可能是系统FreeLibrary延时问题,
    该FreeLibrary并不立即释放Load的函数,而是等待对应的DLL不在被使用时才释放.
      

  13.   

    咋么解决啊,在同一个线程里可以只load一次,但是如果不在线程里,再ontimer里面就只能每次打开、释放了,这内存,一个小时1M的速度递增,有点接受不了啊,运行两天就得重启一次
      

  14.   

    dll中是否引用了sharemem单元?确认有无必要?
    如有必要,确认在主工程里是否也加了sharemem?是不是Freelibrary的问题,不好确定...
      

  15.   

    加过sharemen了,做过好几种测试了,应该是Freelibrary的问题,再ontimer里,不停地load然后free,内存以每次4k的速度递增。万恶的delphi 4k
      

  16.   

    delphi写的dll是有4k的泄漏(有引用control单元...),据说D2007那版也没解决,不知道最新的版本解决了没有。
      

  17.   

    我就不明白了。
    你干嘛要 反复 Load Free?
    你 Load 在那里,程序会死啊?!
      

  18.   


    因为要根据不同的对象调用不同的dll,只能用动态的,反复调用