PostMessage 结构体,消息队列满了?内存泄漏???

okmnji79513 2009-12-27 11:24:01
主线程:

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
procedure My(var m:TMessage);message WM_My;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.My(var m:TMessage);//message WM_My;
var pp:PMyRec;
begin
if m.WParam=0 then
begin
pp:=PMyRec(m.LParam);
// Memo1.Lines.Add(inttostr(pp.i));
FreeMem(pp,sizeof(TMyRec));
end
else if m.WParam=1 then
begin
Memo1.Lines.Add('TABthread finish .');
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var j:HWND;
begin
TABthread.Create(form1.Handle);
end;

end.

子线程:

unit ABThreadU;

interface

uses
Classes, Messages, Windows;

Const
WM_My=WM_USER+1000;

type
TMyRec=record
i:integer;
end;
PMyRec=^TMyRec;

TABthread = class(TThread)
private
FWnd:HWND;
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(H:HWND);
end;

implementation

constructor TABthread.Create(H:HWND);
begin
inherited Create(true);
FWnd:=H;
self.Resume;
end;

procedure TABthread.Execute;
var pp:PMyRec;
i:integer;
begin
for i:=1 to 20000 do
begin
GetMem(pp,sizeof(TMyRec));
pp.i:=i;
PostMessage(FWnd,WM_My,0,integer(pp));
end;
PostMessage(FWnd,WM_My,1,0);
end;

end.


如上代码,每次按下 Button1 时,程序占用内存就增加 几十 到 上百k ,且“PostMessage(FWnd,WM_My,1,0);”不一定能收到。--------①
后来 将循环 减少为 “for i:=1 to 200 do”,第一次按 Button1 时,程序占内存增加了 几十k------②,接着 连续按 Button1 几十次,程序占内存都不会变。

综上现象:
问题:
1、①处,是因为 连续发的消息 太多,窗口消息队列 放不下了?那 窗口消息队列 最多放多少条消息?
2、②处,为什么第一次按 Button1 时,程序占内存会增加 几十k?是因为第一次使用Memo1(打印“TABthread finish .”),程序为Memo1分配所需内存?(我程序刚打开时,Memo1里面是没有任何字符的)
...全文
1040 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
okmnji79513 2009-12-28
  • 打赏
  • 举报
回复
OK 结贴了
lhy 2009-12-28
  • 打赏
  • 举报
回复
消息太多了
dd_zhouqian 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hjkto 的回复:]
创建线程需要为线程分配栈空间
为什么不是堆空间呢?
[/Quote]
栈有个好处不用分配释放很多次

另消息队列满了,不会产生内存泄露
hjkto 2009-12-28
  • 打赏
  • 举报
回复
创建线程需要为线程分配栈空间
为什么不是堆空间呢?
cnzdgs 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hjkto 的回复:]
创建线程需要为线程分配栈空间
为什么不是堆空间呢?
[/Quote]
堆是整个进程共享的,栈是每个线程专用的。
wxsan 2009-12-27
  • 打赏
  • 举报
回复
函数功能:该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回。消息队列里的消息通过调用GetMessage和PeekMessage取得。

函数原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

参数

hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:

HWND.BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口。

NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样。

Msg:指定被寄送的消息。

wParam:指定附加的消息特定的信息。

IParam:指定附加的消息特定的信息。

返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。



okmnji79513 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 hjkto 的回复:]
PostMessage(FWnd,WM_My,0,integer(pp));
  end;
  PostMessage(FWnd,WM_My,1,0);
请教一下楼主,这两句在线程的作用是什么?
[/Quote]
没看懂你的问题, -.-
hjkto 2009-12-27
  • 打赏
  • 举报
回复
PostMessage(FWnd,WM_My,0,integer(pp));
end;
PostMessage(FWnd,WM_My,1,0);
请教一下楼主,这两句在线程的作用是什么?
hjkto 2009-12-27
  • 打赏
  • 举报
回复
跟高手学习 了
cnzdgs 2009-12-27
  • 打赏
  • 举报
回复
任务管理器中的“内存占用”显示的是物理内存,物理内存是由系统调度的,在使用的时候分配,一般情况下如果物理内存资源充足,即使程序释放了内存,系统也不会立即回收物理内存。监视程序使用内存的情况应该看虚拟内存,程序分配和释放内存都是虚拟内存的变化,任务管理器菜单中“选择列”可以设置显示进程占用的虚拟内存。
okmnji79513 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dinoalex 的回复:]
procedure TABthread.Execute;
var pp:PMyRec;
    i:integer;
begin
  FreeOnTerminate := True;  //  <-- 线程完了后释放
[/Quote]
这样,任务管理器 里的数值也是不会减少的。
okmnji79513 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cnzdgs 的回复:]
......
估计你查看的是物理内存,对于重复的操作,多数情况下再第1次执行时物理内存会增加,之后就基本不变了。如果是虚拟内存,是在分配是增加,释放后减少。
[/Quote]
没有全懂,我看的内存变化是直接在任务管理器看的。
你的意思是:如果 我 第一次 按下 Button1 时,物理内存 够用,则 任务管理器 中的数值增加,并在线程TABthread执行完后数值不减少;又 如果 我 第一次 按下 Button1 时,物理内存不够,要用到虚拟内存,则 任务管理器 中的数值增加,并在线程TABthread执行完后数值减少
是不是?
dinoalex 2009-12-27
  • 打赏
  • 举报
回复
procedure TABthread.Execute;
var pp:PMyRec;
i:integer;
begin
FreeOnTerminate := True; // <-- 线程完了后释放
cnzdgs 2009-12-27
  • 打赏
  • 举报
回复
1、对于XP系统,消息队列最多可以放10000条消息,消息队列满了之后,再PostMessage会返回失败。
2、创建线程需要为线程分配栈空间。估计你查看的是物理内存,对于重复的操作,多数情况下再第1次执行时物理内存会增加,之后就基本不变了。如果是虚拟内存,是在分配是增加,释放后减少。

1,184

社区成员

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

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