在线程里FreeLibrary造成内存泄露的问题

山娃马小三儿 2010-09-05 03:19:40
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里啥也没做,就这样了,该怎么处理呀,是不是多次调用而没有释放完全呀,有哪位高人遇到过吗?
...全文
496 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
山娃马小三儿 2010-10-01
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 iamduo 的回复:]
我就不明白了。
你干嘛要 反复 Load Free?
你 Load 在那里,程序会死啊?!
[/Quote]

因为要根据不同的对象调用不同的dll,只能用动态的,反复调用
iamduo 2010-09-26
  • 打赏
  • 举报
回复
我就不明白了。
你干嘛要 反复 Load Free?
你 Load 在那里,程序会死啊?!
金卯刀 2010-09-25
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 jalu_515 的回复:]
加过sharemen了,做过好几种测试了,应该是Freelibrary的问题,再ontimer里,不停地load然后free,内存以每次4k的速度递增。。。。万恶的delphi 4k
[/Quote]
delphi写的dll是有4k的泄漏(有引用control单元...),据说D2007那版也没解决,不知道最新的版本解决了没有。
Frank.WU 2010-09-22
  • 打赏
  • 举报
回复
这个是动态加载库,能不能改为静态加载呢?
金卯刀 2010-09-21
  • 打赏
  • 举报
回复
dll中是否引用了sharemem单元?确认有无必要?
如有必要,确认在主工程里是否也加了sharemem?

是不是Freelibrary的问题,不好确定...
山娃马小三儿 2010-09-21
  • 打赏
  • 举报
回复
哎,悲剧了
山娃马小三儿 2010-09-21
  • 打赏
  • 举报
回复
咋么解决啊,在同一个线程里可以只load一次,但是如果不在线程里,再ontimer里面就只能每次打开、释放了,这内存,一个小时1M的速度递增,有点接受不了啊,运行两天就得重启一次
山娃马小三儿 2010-09-21
  • 打赏
  • 举报
回复
加过sharemen了,做过好几种测试了,应该是Freelibrary的问题,再ontimer里,不停地load然后free,内存以每次4k的速度递增。。。。万恶的delphi 4k
YFLK 2010-09-17
  • 打赏
  • 举报
回复
由15楼想到的可能是系统FreeLibrary延时问题,
该FreeLibrary并不立即释放Load的函数,而是等待对应的DLL不在被使用时才释放.
zhangxuyu1118 2010-09-14
  • 打赏
  • 举报
回复
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的问题。
zhangxuyu1118 2010-09-14
  • 打赏
  • 举报
回复
在主线程中放个时钟,结果也是这样的:
procedure TForm1.Timer1Timer(Sender: TObject);
var
DLLHandle :THandle;
ReturnValue: integer;
begin
DLLHandle :=LoadLibrary(PChar('midas.dll'));
try
ReturnValue := 10;
finally
FreeLibrary(DLLHandle);
end;
end;
金卯刀 2010-09-13
  • 打赏
  • 举报
回复
测试了一下,确实内存占用会不断增加。但在停止该线程后,用getModuleHandle检测dll是否在进程空间内,返回的句柄是0,说明该dll已经被卸载了。
所以,应该是其它地方引起的内存泄漏,真相不明...
金卯刀 2010-09-13
  • 打赏
  • 举报
回复
不应该是dll的问题,即使你反复loadlibrary,只会存在一份镜像...
山娃马小三儿 2010-09-13
  • 打赏
  • 举报
回复
只load不free就好了,程序结束的时候,会自动free掉,只能这么干了,实在想不出法子来,反正多次load也是只load了一次
iamduo 2010-09-08
  • 打赏
  • 举报
回复
我好像在哪里见过这样的说法。
LoadLibrary
其实MS做了一些手法的。并不是立马就真的“Load”,是在合适的时候才“Load”。
大概的意思是,这里会有个Delay。
所以,我想的是,这个 API 并不像我们自己写的 exports dll 那么直白。更加像是个 COM 函数。

另,线程中,应该sleep一下,哪怕是sleep(0)也是有意义的,表示放出时间片给主线程。

lz 不应该这样试验代码。就一段最简单的动态加载。然后用内存检验工具看一下。比如:AQTime 之类的。
比较好。

谁的程序不泄露? 用 FastMM 看一下吧,但凡是 D 写的,多少都有那么几个的。这是没有办法的事情。
多数原因都是“用空间换时间”造成的。
能容忍的话,就当没看见好了。
zhangxuyu1118 2010-09-08
  • 打赏
  • 举报
回复
还是在增加的,只是慢了些,推翻自个的结论,观看其他人的解释。
zhangxuyu1118 2010-09-08
  • 打赏
  • 举报
回复
//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;

结论: 释放内存需要时间的。
zhangxuyu1118 2010-09-08
  • 打赏
  • 举报
回复
的确如此,关注中。
starluck 2010-09-06
  • 打赏
  • 举报
回复
[Quote=引用楼主 jalu_515 的回复:]
procedure TThreadResoveData.Execute;
var
DLLHandle :THandle;
begin
while not Terminated do
begin
Try
DLLHandle :=LoadLibrary(PChar('MODBUS.dll'));
Finally
Free……
[/Quote]

可能是dll 自己维护着点什么吧。
kye_jufei 2010-09-06
  • 打赏
  • 举报
回复
你要設置斷點或找個工具看一下是哪句內存洩露了。。。
加载更多回复(4)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧