delphi 多线程程序中内存不断上升的问题!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi 多线程程序中内存不断上升的问题!相关的知识,希望对你有一定的参考价值。

我这个是循环程序,为什么内存不停的上升呢?有没有好的办法??
窗体代码:
MyThread:=a121.Create(false);
memo1.Lines.Add(inttostr(MyThread.ThreadID)) ;
MyThread.Resume;
多线程代码:
procedure a121.Execute;
var
i:integer;
HttpCli1: THttpCli;
begin
HttpCli1:= THttpCli.Create(nil);
HttpCli1.RequestVer:='1.1';
for i:=0 to 500 do
begin
C:=i;

HttpCli1.URL:='http://www.qq.com/' ;
HttpCli1.RcvdStream:=TMemoryStream.Create;

try
HttpCli1.Get;
except

end;
HttpCli1.RcvdStream.Seek(0,0);
//HttpCli1.RcvdStream.Free;
setlength(httpcode,HttpCli1.RcvdStream.size);
HttpCli1.RcvdStream.Read(httpcode[1],length(httpcode));
sleep(100);
end;
end;

事实上,你在循环内创建了500次HttpCli1.RcvdStream:=TMemoryStream.Create;

HttpCli1:= THttpCli.Create(nil); 也需要释放。追问

能不能彻底的释放完?我怎么感觉内存还是在上升呢?呵呵

追答

如果你在每个对象使用完之后及时释放,内存不会无故上升,HttpCli1.RcvdStream.Read(httpcode[1],length(httpcode));在工作,也是需要内存开销的。属于正常。

参考技术A HttpCli1.RcvdStream:=TMemoryStream.Create;

应该在循环前创建,循环后销毁,你这是等待50秒吗?貌似很怪异哦追问

我这个程序是个循环程序不能让它占用太多CPU呀!

参考技术B HttpCli1:= THttpCli.Create(nil);

创建了但是没有销毁。追问

销毁了内存还会不会上升呢?

追答

销毁了自然不会出现那样的问题。
你试试看嘛,只是把注释掉的放在循环外边。

DELPHI下多线程编程的几个思维误区(QDAC)

有几个网友私下问我一些有关线程的事情。过节写个东西上来大家交流。

 

思维误区1,自己新建的THREAD是线程,自己的主程序不是线程. 很多人在多线程编程没有把主线程也当作线程。其实主线程也是线程。看起来是废话,这个话确实很重要,这个就意味着,在DELPHI中,不光你开的线程,还有你的主线程所有的内存分配也是串的,进锁排队的。主线程和线程的区别

A.一般来说主线程的优先级高了点。(当然你也可以自己设置)

B.主线程在WIN下是处理APPLICATION的消息。

其他基本与你自建线程无区别。

所以这一点还可以点破小白问题,比如主线程不能进锁。其实主线程也要进锁的。关键是主线程不能挂起死等。挂起死等就用户界面卡了或者假死了。所以要进代码一边等,一边切换到其他任务。

 

思维误区2.线程和面向对象。

C的时候写线程反而很简单。因为C不是面向对象的。 撸代码的时候非常清楚什么在线程,什么在主线程,因为撸代码思维和机器表现一致。但是DELPHI是面向对象的。经常老会问自己类似这样的问题:这个对象在主线程还是在线程。这个OO中毒太深了,这个问题我也问过。其实DELPHI也不是绝对的面向对象,只是面向对象的封装而已,其本质还是流式代码跟C没区别,也就是跟OO没有半毛关系。

那问 这个对象在线程跑还是在主线程跑? 我只能说,所有对象都在内存,至于你哪里跑要看你的线程走了多少代码。比如

 

TAAAA= CLASS;

Public

procedure A;

procedure B;

procedure C;

(假设Procedure A,B,C相互没有资源冲突和相互调用)

APP代码你调用了Procedure A. 建了一个线程,线程调用Procedure B, 线程结束。

主线程跑了Procedure A, 自己建的线程跑了Procedure B. 但是他们都属于类TAAAA。

所以思维要改回来,线程跟面向对象没有半毛钱关系。不要用面向对象的思维去设计你的线程。这样你就知道你的锁该放在哪里了。

 

思维误区3. 锁和无锁

    很多编程书里把锁讲成如厕(群里我把这个比喻成偷人,因为如厕不够污,记不住,偷人够污,容易记住。)。一个人进了厕所,其他人在门外面等着。锁就是门,人就是线程。这样的设置就是竞争机制,厕所少,人多啊。假如没有竞争机制,那当然不要锁了,每人发一个厕所,人人都幸福啊。编程中,比如固定的配置数据,你跑线程的时候每个线程配一个复本。那就不要锁了。

锁是影响你的程序效率的。犹如这边要尿急了,厕所里的人还没有出来,心里OS,TMD上个厕所真麻烦。 你要降低锁在程序里的开销。无非几个有因素:

A.锁本身的开销。(好比:上厕所里面的人出来,外面的人进去本身要时间的,这个就是锁的开销–我是乱比喻了,其实不是这样的,但是本质差不多,这样讲便于理解)。所以操作系统提供很多锁的资源和方式,所谓原子锁。其实也是锁。

B,线程等太久。

犹如上厕所等太久,多费劲啊。要解决也就2个方面,

B1,里面的人蹲太长时间了,憋死了。所以你要尽量使你的LOCK里面的任务减少。防止蹲太久.

B2,等的人太多。。排队排到大街上了。所以你要规划好你的资源。让资源分片—这个做法好比设了多个厕所。解决方案还有一个就是线程池。就是减少人。这个用如厕的比喻估计更加污。还是表达出来便于理解。“犹如,设几个人把所有人的大便都拉了。”

很多事,道理真的就这么简单。设计线程模型的时候别想多了就行。难就难在设计的时候自己容易想多,想着想着就无解了,那是自己给自己的坑啊。

 

http://blog.qdac.cc/?p=4564

以上是关于delphi 多线程程序中内存不断上升的问题!的主要内容,如果未能解决你的问题,请参考以下文章

delphi 7 做多线程程序,内存不断增加,怎么解决?

Delphi 如何用多线程进行数据采集

JAVA-初步认识-第十二章-多线好处与弊端

Java多线程程序设计初步入门

在多线程环境中使用 PyCurl 时程序消耗的内存不断增长

Python 多进程多线编程模板