不会吧。我在有udp数据的时候是暂停线程的,在udp包收完后,我在把线程resume的,我觉得绝对不是我的申请的内存没有释放,肯定是别的原因,因为如果是我申请的内存,那肯定不会在我把程序界面最大化最小化的时候释放。而一个已经是80多M的内存占有量一下子变成3,4M,那就比较奇怪了。。

解决方案 »

  1.   

    呵呵,在下以前也遇过类似问题,至今未解, 也想同时请高手指教! 具体如下:我在NT下通过注册表中的NT 性能数据实时读取当前的所有进程, 取得期PID,名称, 运行时间,线程数,所用内存大小等,相当于作出任务管理器类似的功能,但程序在NT Server下出现过每读取一次数据,内存就涨十几K的事,但NT WorkStation 下正常,在NT Server下也并非所有的机器上都这样,只有几台机器上是这样? 我跟踪进去,发现问题可能是出在读注册表时的一个API函数调用上,调用一次就涨内存10几K, 我自己的缓冲区的静态的!
      

  2.   

    线程是一直执行的,系统开销比较大,在处理数据缓冲同步时会出现很多问题,处理UDP这样的东西使用消息响应机制比较好,因为当你知道来UDP数据时操作系统已经把数据缓冲了,没必要自己检测缓冲.
    可以自己定义消息,在有UDP数据时发送并响应该消息来处理数据.
    线程用于实时采集系统可以提高程序性能,另外不要在塞扬CPU上用线程.
      

  3.   

    unit Main;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ActnList, NMUDP, Menus, ImgList, StdCtrls, ExtCtrls, ComCtrls, ToolWin,
      Db, ADODB ,ShellApi,DBTables,PMDbAgt;Const
      MY_TRAY_ICON=1000;
      WM_TrayMessage=2000;
      MaxShare =1000 ;
    type
      TfrmMain = class(TForm)
        ToolBar1: TToolBar;
        ToolButton5: TToolButton;
        ToolButton3: TToolButton;
        ToolButton4: TToolButton;
        ToolButton6: TToolButton;
        mmInfo: TMemo;
        imgMenu: TImageList;
        mmnBar: TMainMenu;
        FileItem: TMenuItem;
        Receive: TMenuItem;
        Stop: TMenuItem;
        sacda1: TMenuItem;
        NCZ: TMenuItem;
        NYC: TMenuItem;
        NYX: TMenuItem;
        NDZ: TMenuItem;
        NDD: TMenuItem;
        N2: TMenuItem;
        N3: TMenuItem;
        N16: TMenuItem;
        nPort: TMenuItem;
        N6: TMenuItem;
        nuGetLnk: TNMUDP;
        Action: TActionList;
        ActReceive: TAction;
        ActStop: TAction;
        Act_Exit: TAction;
        N1: TMenuItem;
        GetUDPHead: TAction;
        timeCls: TTimer;
        pmTray: TPopupMenu;
        procedure nPortClick(Sender: TObject);
        procedure ActReceiveExecute(Sender: TObject);
        procedure ActStopExecute(Sender: TObject);
        procedure Act_ExitExecute(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure timeClsTimer(Sender: TObject);
        procedure WMTrayMessage(var  msg:TMessage); Message WM_TrayMessage;
        procedure FormDestroy(Sender: TObject);
        procedure AppMinimized(Sender:TObject);
        procedure N3Click(Sender: TObject);
        procedure nuGetLnkDataReceived(Sender: TComponent;
          NumberBytes: Integer; FromIP: String; Port: Integer);
      private
        { Private declarations }
        Procedure ReRegisterPort(Port: String);
        Function ReadRegisterPort ( Var Port : String):Boolean;
      public
        { Public declarations }
        Port : String ;
      end;  TResolveData = Class(TThread)
      public
        procedure Execute;override;
      end;
    var
      Num : Integer;
      Lx : Integer ;
      SharePool : TList ;
      HeadPointer,TailPointer : Integer;
      ResolveData : TResolveData ;
      frmMain: TfrmMain;
      nid:TNOTIFYICONDATA ;
      EventHanle:  Integer;
      Start : Boolean ;
      Switch : Boolean ;implementation{$R *.DFM}
    Uses Registry ,RData, commondb;procedure TfrmMain.nPortClick(Sender: TObject);
    var
      PortNum : Integer ;
    begin
        if InputQuery('ÇëÊäÈë', '½ÓÊܶ˵Ķ˿ںÅ', Port) then
           PortNum := StrToIntDef(Port,-1)
        else Exit;
        if PortNum=-1 then
        begin
          ShowMessage('²»ÕýÈ·µÄ¶Ë¿ÚºÅ£¬ÇëÖØÐÂÊäÈë');
          Exit ;
        end;
        nuGetLnk.LocalPort := PortNum ;
        ReRegisterPort(Port);
    end;Procedure TfrmMain.ReRegisterPort(Port: String);
    var
      Reg:TRegistry;
    begin
      Reg := TRegistry.Create;
      Reg.RootKey:=HKEY_CURRENT_USER;
      try
        Reg.OpenKey('\Mis_Settings\Port',True);
        Reg.WriteString('Port',Port);
      except
        ShowMessage('½¨¼ü´íÎó£¡');
        Reg.CloseKey;
        Reg.Free;
        Exit;
      end;
      Reg.CloseKey;
      Reg.Free;
    end;Function TfrmMain.ReadRegisterPort ( Var Port : String):Boolean;
    var
      Reg:TRegistry;
    begin
      Result:=False;
      Reg := TRegistry.Create;
      Reg.RootKey:=HKEY_CURRENT_USER;
      if Reg.OpenKey('\Mis_Settings\Port',False) then
      begin
        Port:=Reg.ReadString('Port');
        Result := True ;
      end;
      Reg.CloseKey;
      Reg.Free;
    end;procedure TfrmMain.ActReceiveExecute(Sender: TObject);
    begin
      Start := True ;
      ActReceive.Enabled := False;
      ActStop.Enabled := True;
    end;procedure TfrmMain.ActStopExecute(Sender: TObject);
    begin
      Start := False ;
      ActReceive.Enabled := True;
      ActStop.Enabled := False;
    end;procedure TfrmMain.Act_ExitExecute(Sender: TObject);
    begin
      Free;
    end;procedure TfrmMain.FormShow(Sender: TObject);
    begin
      Start := False ;
      if Not ReadRegisterPort(Port) then ShowMessage('ÇëÉèÖýÓÊܶ˿ںÅ')
         else nuGetLnk.LocalPort := StrToInt(Port);
      lx := 0 ;
      Num := 0 ;
      Switch := False ;
    end;procedure TfrmMain.FormCreate(Sender: TObject);
    var
      I : Integer ;
      Tmp : TMemoryStream ;
    begin
      SharePool := TList.Create ;
      Application.OnMinimize:=AppMinimized;
      AppMinimized(nil);
      DM := TDM.Create(nil);
      For I := 1 to MaxShare do
      begin
        Tmp := TMemoryStream.Create ;
        SharePool.Add(Tmp);
      end;
      HeadPointer := 0 ;
      TailPointer := 0 ;
      ResolveData := TResolveData.Create(False);
      SetEvent(EventHanle);
    end;procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      DM.Free ;
    end;procedure TfrmMain.timeClsTimer(Sender: TObject);
    begin
      mmInfo.Lines.Clear ;
      Switch := Not Switch ;
    end;procedure TfrmMain.WMTrayMessage(var  msg:TMessage);
    var
        p:TPoint;
    begin
        if  msg.LParam=WM_LButtonDown  then
        begin
            ShowWindow(Application.Handle,SW_Show);
            Application.Restore;
        end
        else  if  msg.LParam=WM_RButtonDown  then
        begin
            GetCursorPos(p);  //»ñÈ¡¹â±êλÖÃ
            pmTray.Popup(p.x,p.y);    //ÏÔʾµ¯³ö²Ëµ¥
        end;
    end;
      

  4.   


    procedure TfrmMain.AppMinimized(Sender:TObject);
    var
      MyICon : TICon;
    begin
      NID.cbSize:=SizeOf(TNotifyIconData);
      MyICon := TICon.Create ;
      imgMenu.GetIcon(0,MyICon);
      NID.hIcon:=MyICon.Handle;
      NID.szTip:=  'Íø¹Ø';
      NID.uCallbackMessage:=WM_TrayMessage;
      NID.uFlags:=NIF_ICON  or  NIF_MESSAGE  or  NIF_TIP;
      NID.uID:=0;
      NID.Wnd:=Handle;
      Shell_NotifyIcon(NIM_ADD,@NID);
      ShowWindow(Application.Handle,SW_Hide);
    end;procedure TfrmMain.FormDestroy(Sender: TObject);
    var
      I : Integer ;
    begin
      Shell_NotifyIcon(NIM_DELETE,@NID);
      For I := 1 to MaxShare do
      begin
        TMemoryStream(SharePool.Items[I-1]).Free ;
        SharePool.Items[I-1] := nil;
      end;
      SharePool.Free ;
    end;procedure TfrmMain.N3Click(Sender: TObject);
    begin
      mmInfo.Lines.Clear ;
    end;procedure TfrmMain.nuGetLnkDataReceived(Sender: TComponent;
      NumberBytes: Integer; FromIP: String; Port: Integer);
    var
      Pos : Integer ;
    begin
      ResolveData.Suspend ;
      if ((HeadPointer+1) mod MaxShare)<>TailPointer  then
      begin
        Pos:= (HeadPointer+1) mod MaxShare;
        TMemoryStream(SharePool.Items[HeadPointer]).Clear ;
        nuGetLnk.ReadStream(TMemoryStream(SharePool.Items[HeadPointer]));
        ResetEvent(EventHanle);
        HeadPointer := Pos ;
        SetEvent(EventHanle);
      end;
      ResolveData.Resume ;
    end;procedure TResolveData.Execute;
    var
      Buff : TMemoryStream ;
      PHead : Array[0..7] of Char ;
    begin
      Buff := TMemoryStream.Create ;
      While True do
      begin
        if (Not Start) then  Continue ;
        if Switch  then
        begin
          DM.DbAgent.Disconnect ;
          bSuccess := True;
          try
            DM.DbAgent.Connect('CYDB','ORACLEUSER', 'USER', '');
          except
            bSuccess := False;
          end
        end ;
        if (Not bSuccess) then Continue ;
        if HeadPointer<>TailPointer then
        begin
          TailPointer :=(TailPointer+ 1) mod MaxShare;
          Buff.LoadFromStream(TMemoryStream(SharePool.Items[TailPointer]));;
          Buff.Position :=0 ;
          Buff.Read(PHead,8);
          if Integer(PHead[0]) = 0 then
          begin
            Case Integer(PHead[1]) of
            0 : begin
                  if lx=0 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;
                  lx := 0 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;&Ograve;&pound;&sup2;&acirc;&Ecirc;&yacute;&frac34;&Yacute;...');
                  YCDataReceive(PHead,Buff);
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'&Ograve;&pound;&sup2;&acirc;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end;
            {1 : begin
                  if lx=1 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;              lx := 1 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;&micro;&ccedil;&para;&Egrave;&Ecirc;&yacute;&frac34;&Yacute;...');
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'&micro;&ccedil;&para;&Egrave;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end;}
            2 : begin
                  if lx=2 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;              lx := 2 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;&Ograve;&pound;&ETH;&Aring;&Ecirc;&yacute;&frac34;&Yacute;...');
                  YXDataReceive(PHead,Buff);
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'&Ograve;&pound;&ETH;&Aring;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end;
            3 : begin
                  if lx=3 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;
                  lx := 3 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;&micro;&para;&Otilde;&cent;&Ecirc;&yacute;&frac34;&Yacute;...');
                  //DZDataReceive(PHead,Buff);
                  YXDataReceive(PHead,Buff);
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'&micro;&para;&Otilde;&cent;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end;
            {4 : begin
                  if lx=4 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;              lx := 4 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;±&pound;&raquo;¤&ETH;&Aring;&ordm;&Aring;&Ecirc;&yacute;&frac34;&Yacute;...');
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'±&pound;&raquo;¤&ETH;&Aring;&ordm;&Aring;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end;
            5 : begin
                  if lx=5 then Num := Num + 1
                     else
                     begin
                       frmMain.mmInfo.Lines.Add(Inttostr(lx)+'  ' +Inttostr(Num));
                       Num :=1 ;
                     end;
                  lx := 5 ;
                  frmMain.mmInfo.Lines.Add('&Otilde;&yacute;&Ocirc;&Uacute;&frac12;&Oacute;&Ecirc;&Uuml;×&acute;&Igrave;&not;&Aacute;&iquest;&Ecirc;&yacute;&frac34;&Yacute;...');
                  frmMain.mmInfo.Lines.Add(FormatDateTime('YYYY/MM/DD HH:NN:SS',Now)+'×&acute;&Igrave;&not;&Aacute;&iquest;&Ecirc;&yacute;&frac34;&Yacute;&frac12;&Oacute;&Ecirc;&Uuml;&Iacute;ê±&Iuml;');
                  frmMain.mmInfo.Lines.Add('');
                end; }
            end;
          end;
        end;
      end;
      Buff.Free ;
    end;
    end.
      

  5.   

    但是我必须对缓冲区的数据进行处理,如果我不用线程,那我会丢失udp数据包,而且丢的非常厉害。在用线程机制后,我就不再丢包了。。