简体   繁体   English

内存泄漏,滥用线程?

[英]Memory leak, misuse of thread?

Im trying to use the threads for the first time, but cant tell why am i getting memory leak, cause of misuse of the thread, or cause im that stupid and forgot to free something, but at this point, i cant tell, which one (or both) is it.我第一次尝试使用线程,但不知道为什么我会出现内存泄漏,线程滥用的原因,或者导致我愚蠢而忘记释放某些东西,但在这一点上,我不知道是哪个(或两者)是它。

This is the procedure that is being called on click这是单击时调用的程序

procedure TmainForm.scrollFrameClick(item:TEquipmentItem; itemFrame:TitemFrame);
begin
item.fullImage:=itemFrame.itemImage.Picture.Graphic;
setCurrentSearchItem(item);
end;

Procedure that calling thread调用线程的过程

procedure TmainForm.setCurrentSearchItem(item:TEquipmentItem);
begin

if not(assigned(searchResultTable)) then
  searchResultTable:=TItemHtmlTable.Create
else
  begin
    freeandnil(searchResultTable);
    searchResultTable:=TItemHtmlTable.Create;
  end;

if getDomTh<>nil then
  if getDomTh.Finished then
    begin
      getDomTh.Terminate;
      getDomTh.WaitFor;
      FreeAndNil(getDomTh);
    end
  else
    begin
      getDomTh.WaitFor;
      getDomTh.Terminate;
      FreeAndNil(getDomTh);
    end;

getDomTh:=TCreateDomThread.Create(false,'http://www.example.com/ru/items/'+inttostr(item.ID),searchResultTable.DomTree);

currentItemImage.Picture.Graphic:=item.fullImage;
itemNameLab.Caption:=item.ItemName;
itemTypeLab.Caption:=item.ItemTypeName;
itemSubtypeLab.Caption:=item.ItemSubtypeName;

/////////////////
// At this point i would call a thread and use the result from the "searchResultTable"
/////////////////

if getDomTh<>nil then
  if getDomTh.Finished then
    freeandnil(searchResultTable)
  else
    begin
      getDomTh.WaitFor;
      getDomTh.Terminate;
      FreeAndNil(getDomTh);
      freeandnil(searchResultTable);
    end;
end;

This is the thread unit这是线程单元

unit threadUnit;

interface

uses System.Classes,System.SysUtils, parser;

type
  TCreateDomThread = class(TThread)
  private
    pDomTree:TDomTree;
    pUrl:string;
  public
    property tDomTree:TDomTree read pDomTree write pDomTree;
    property tUrl:string read pUrl write pUrl;
    constructor Create(suspended:boolean; Url:string; DomTree:TDomTree);
    procedure Execute; override;
  end;

implementation

uses main;


constructor TCreateDomThread.Create(suspended:boolean; Url:string; DomTree:TDomTree);
begin
  tDomTree:=DomTree;
  tUrl:=Url;
  inherited Create(suspended);
end;

procedure TCreateDomThread.Execute;
begin
    if Terminated then Exit;
    mainForm.getDomTree(tUrl, tDomTree);
end;
end.

DomTree retrieval DomTree 检索

 procedure TmainForm.getDomTree(url:string; outputDomTree:TDomTree);
    var
      HtmlTxt: string;
    begin
      try
        HtmlTxt := IdHTTP1.Get(url);
        if not outputDomTree.RootNode.RunParse(HtmlTxt) then
          TThread.Queue(nil,procedure begin showmessage('Can'#39'tParse HTML!') end);
      except
        on E: Exception do
          TThread.Queue(nil,procedure begin ShowMessage(E.ClassName + ' : ' + E.Message); end);
      end;
    end;

If you call for the click a couple of times, taskmanager shows that committed memory is always increasing.如果您多次调用单击,任务管理器会显示提交的内存始终在增加。 I had no luck with debugging that, any advise would be much appreciated.我没有调试成功,任何建议将不胜感激。

EDIT:编辑:

So there is a bunch of TDomTree which are not being free, but i couldnt understand, from where, cause thread is destroyed as expected所以有一堆TDomTree不是免费的,但我无法理解,从哪里,导致线程按预期被破坏

Delphi memory manager screenshot Delphi 内存管理器截图

EDIT 2: Found the error.编辑 2:发现错误。

So i found the issue.所以我发现了这个问题。 StringList from the TDomTree was referenced in thread that updated the ui.来自TDomTree StringList在更新 ui 的线程中被引用。 So therefore, when worker thread tried to destroy the searchResultTable , its TDomTree 's StringList could not be terminated, creating exception, so whole TDomTree was not terminating.因此,当工作线程试图销毁searchResultTable ,其TDomTreeStringList无法终止,从而产生异常,因此整个TDomTree并未终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM