内存不断增长,究竟是什么原因?

bwe2009 2012-04-30 09:34:42
我的程序中使用了线程,线程中使用了adodataset和idhttp
大致如下:
1、线程用的是TThread,主要代码在Execute,用完肯定全部释放动态创建的数据
2、adodataset在线程中需要open或访问或保存数据。
3、IDHTTP在线程中get方法打开网页。

大致主要操作就是这样的。线程是根据情况反复创建实例和销毁实例。

用内存泄露工具检查,只发现几个tstringlist没释放,这几个tstringlist也只是初始化读取少量几条数据,并在程序中只读不写,更没有ADD,应该不存在内存增加的状况。

请问,这里内存不断增加会是什么原因?
我分析:
1、可能是线程释放不对?我已在每个实例线程开始段写了FreeOnTerminate := true;
例如procedure a.Execute;
begin
FreeOnTerminate := true;
try

finally
...free;//凡是涉及到动态创建的全部释放
...
...
...
...free;//凡是涉及到动态创建的全部释放
end;
end;

2、ADO内存泄露?我用的ADODATASET控件,会泄露吗?
我使用的方法就是open apeend edit post这几种,难道有泄露?

3、由于反复创建和销毁实例线程,内存碎片得不到及时清理,导致内存不断增加?
...全文
1733 69 打赏 收藏 转发到动态 举报
写回复
用AI写文章
69 条回复
切换为时间正序
请发表友善的回复…
发表回复
cntigercat 2013-03-31
  • 打赏
  • 举报
回复
明确的创建对象,不要用 with tobjcet.crecat do这样的
mpg2012 2013-03-30
  • 打赏
  • 举报
回复
引用 86 楼 sololie 的回复:
下载fastmm,解压后把 ..FastMM\Replacement BorlndMM DLL\Delphi\Precompiled\for Delphi IDE\Performance\BorlndMM.dll 替换 delphi \bin 目录下的 BorlndMM.dll。 delphi 下把fastmm 目录加入 library path。 在项目(exe、dll)和引用到该项目……
学习了, 目前正得上, 经常报内存出错的问题, 烦了个把月了,虽然目前用异常处理的方法处理了, 可是程序还是不稳定, 这了内存报错工具, 真是太好了
Andy-88 2013-03-20
  • 打赏
  • 举报
回复
神们小弟写的线程 少 你们说的内存泄露
sololie 2013-03-19
  • 打赏
  • 举报
回复
下载fastmm,解压后把
..FastMM\Replacement BorlndMM DLL\Delphi\Precompiled\for Delphi IDE\Performance\BorlndMM.dll 替换 delphi \bin 目录下的 BorlndMM.dll。
delphi 下把fastmm 目录加入 library path。

在项目(exe、dll)和引用到该项目的其他项目 的入口点

program Project1;

uses
FastMM4,
Forms,
Unit1 in 'Unit1.pas' {Form1};
.....

library Project2; // 如果是DLL项目
uses
FastMM4,
SysUtils,
Classes;


这样,就程序一当有内存泄露发生,就会弹出提示窗口,并给出泄露的根源。
可以这样测试,建立个空窗体项目:


// 入口点 uses fastmm4
program Project1;
uses
FastMM4,
.....

// 窗体中做个内存泄露测试

procedure TForm1.FormCreate(Sender: TObject);
begin
TObject.Create;
end;


// 编译运行程序,关闭程序后就会出现泄露提示


如果要设计多线程的测试,一定要查看 FastMM4Options.inc 中的注释说明。

另外,可将 ..FastMM\Translations\Chinese (Simplified) 下所有语言文件覆盖 ..FastMM\ 下的同名文件。
sololie 2013-03-19
  • 打赏
  • 举报
回复
测试内存泄露,用fastmm。如果涉及多线程,注意查看 FastMM4Options.inc 里的注释。
bwe2009 2013-02-24
  • 打赏
  • 举报
回复
问题提前。问题提前。
mhhaifeng 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 的回复:]
无代码无真相
[/Quote]
支持
楼主是要我们 充分发挥下自己的想象力
bwe2009 2012-05-03
  • 打赏
  • 举报
回复
一直缓慢增加还是增加到一定程度就不再增长?

基本是缓慢增长。

可能的原因
1 数据库操作使用了事务,没提交或回滚
2 idhttp.get()获得的内存没释放
3 其它

1、怎么讲?
2、idhttp.get()获得的内存怎么释放?

我IDHTTP代码如下:
function find._Get(var url,scookie : String;var idh:tidhttp) : String;
var
stream,outstream : TMemoryStream;
decomp : TIdCompressorZLibex;
ss:pchar;
begin
try
resp.Clear ;
idh.Request.CustomHeaders.Text :=scookie;
ss:=pchar(idh.Get(url));
if AnsiCompareText('gzip',idh.Response.ContentEncoding) = 0 then
begin
try
stream := TMemoryStream.Create;
stream.Write(Pchar(ss)^,Length(ss));
stream.Position := 0;
decomp := TIdCompressorZLibex.Create(nil);
outstream := TMemoryStream.Create;
decomp.DecompressGZipStream(stream,outstream);
outstream.Position := 0;
resp.LoadFromStream(outstream);
Result := resp.Text;
finally
freeandnil(decomp);
freeandnil(outstream);
freeandnil(stream);
end;
end
else
Result :=ss;
idh.Disconnect ;
except
Result :='';
idh.Disconnect ;
//freeandnil(stream);
errorflag:=1;
end;
end;


JohnYale 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 的回复:]

这个问题不在于是
try..except还是try...finally上
看到网上类似的问题很多,没有1个是回答道满意的。
目前随便用try..except还是try...finally,内存缓慢增加是事实。请问还有什么原因?
[/Quote]
同感。

可能的原因
1 数据库操作使用了事务,没提交或回滚
2 idhttp.get()获得的内存没释放
3 其它
bwe2009 2012-05-03
  • 打赏
  • 举报
回复
问题提前。
BambooCaep 2012-05-02
  • 打赏
  • 举报
回复
一直缓慢增加还是增加到一定程度就不再增长?
山东蓝鸟贵薪 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 75 楼 的回复:]
回到话题。资源都释放了,哪里还有使内存缓慢增加的问题呢?
[/Quote]
一般情况都是“逻辑代码错误”,才浪费内存资源的
BambooCaep 2012-05-02
  • 打赏
  • 举报
回复
试试在debug模式下dpr文件里加入reportmemoryleak:=true;
bwe2009 2012-05-02
  • 打赏
  • 举报
回复
回到话题。资源都释放了,哪里还有使内存缓慢增加的问题呢?
管理员 2012-05-02
  • 打赏
  • 举报
回复
骂人的话清理了,给你们留几个回复,鉴证你们的友谊用,哈哈
bwe2009 2012-05-01
  • 打赏
  • 举报
回复
大家稍安勿躁。都是年轻人,火气大可以理解。谢谢大家的关注。
PENG8018 2012-05-01
  • 打赏
  • 举报
回复
要使用 try except
BambooCaep 2012-05-01
  • 打赏
  • 举报
回复
Try...finally Statements
Sometimes you want to ensure that specific parts of an operation are completed, whether or not the operation is interrupted by an exception. For example, when a routine acquires control of a resource, it is often important that the resource be released, regardless of whether the routine terminates normally. In these situations, you can use a try...finally statement.

The following example shows how code that opens and processes a file can ensure that the file is ultimately closed, even if an error occurs during execution:

Reset(F);
try
... // process file F
finally
CloseFile(F);
end;
The syntax of a try...finally statement is

try statementList1 finally statementList2 end
where each statementList is a sequence of statements delimited by semicolons. The try...finally statement executes the statements in statementList1 (the try clause). If statementList1 finishes without raising exceptions, statementList2 (the finally clause) is executed. If an exception is raised during execution of statementList1, control is transferred to statementList2; once statementList2 finishes executing, the exception is re-raised. If a call to the Exit, Break, or Continue procedure causes control to leave statementList1, statementList2 is automatically executed. Thus the finally clause is always executed, regardless of how the try clause terminates.

If an exception is raised but not handled in the finally clause, that exception is propagated out of the try...finally statement, and any exception already raised in the try clause is lost. The finally clause should therefore handle all locally raised exceptions, so as not to disturb propagation of other exceptions.
BambooCaep 2012-05-01
  • 打赏
  • 举报
回复
唯一会导致fianlly不执行的pascal语句就是halt。嵌入式汇编没测试。
bwe2009 2012-05-01
  • 打赏
  • 举报
回复
对,fianlly不能捕获异常,执行是肯定的。区别在此。
加载更多回复(49)

1,183

社区成员

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

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