首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从另一个线程运行的管道上的OmniThreadLibrary内存泄漏(消耗)

从另一个线程运行的管道上的OmniThreadLibrary内存泄漏(消耗)
EN

Stack Overflow用户
提问于 2016-04-19 07:40:33
回答 1查看 318关注 0票数 0

我从另一个线程运行管道(来自OmniThreadLibrary的线程管道),得到内存泄漏,或者更确切地说,是内存消耗。但是当应用程序关闭时,就可以了,并且没有内存泄漏报告(ReportMemoryLeaksOnShutdown := True;)。

这里的例子:点击10次按钮,测试应用程序将得到大约600 MB的内存。Windows 7 x64,Delphi XE6,最新的全功能源代码。

是个窃听器?还是我需要用另一种密码?

代码语言:javascript
复制
uses
  OtlParallel,
  OtlCommon;

procedure TForm75.Button1Click(Sender: TObject);
begin
  // run empty pipeline from another threads
  Parallel.&For(1, 100).Execute(
    procedure(value: integer)
    var
      pipe: IOmniPipeline;
    begin
      pipe := Parallel.Pipeline
        .Stage(procedure(const input: TOmniValue; var output: TOmniValue) begin end)
        .Run;
      pipe.Cancel;
      pipe.WaitFor(100000);
      pipe := nil;
    end
  );
end;

编辑1:用ProcessExplorer测试了代码,发现运行时线程计数是常数的,但是句柄计数是增长的。如果我在"for循环“的末尾插入Application.ProcessMessages; (在管道的代码之后),那么测试应用程序运行良好,句柄关闭,内存消耗是恒定的。不知道为什么。

EN

回答 1

Stack Overflow用户

发布于 2016-04-19 15:52:11

它创建了多少个线程?

例如,在SysInternals Process中检查它。或者在Delphi中(查看->调试->线程)

我认为,因为您为一个长WaitFor阻塞了每个工作线程,所以您的应用程序会为每个按钮单击创建许多工作线程,而当您单击它10次时,它将创建10倍多的线程。

是的,像Windows线程这样的通用操作系统是昂贵的!谷歌为"windows线程内存足迹“--并乘以10个并行创建的线程数量-为您生成的循环。

这就是为什么为了使高度并行的服务器应用程序能够创建轻8个应用程序级线程和绕过OS线程的特殊方法,举几个例子。

然而,作为泛型线程的通用库,OTL对一般线程的限制很小,但依赖于OS提供的本机线程,在创建/释放Windows线程所需的CPU时间(通过线程池概念减轻)和通过OS维护每个Windows线程所需的内存占用(这是不可避免的,并且您可以看到其表现形式)方面,OTL都很昂贵。

当然,当所有这些循环都通过时,它们的线程将被关闭并释放,以及用于维护它们的内存。因此,一旦您等待足够多的线程终止,就不会有内存泄漏--它们是的,所有临时分配的内存都用作它们的工作位置。

UPD。如何验证这一假设?最简单的方法是更改For-循环的每个实例(每次单击按钮)产生了多少线程。

请参阅您的.NumTasks对象的Parallel.For选项:

http://otl.17slon.com/book/chap04.html#leanpub-auto-iomniparallelsimpleloop-interface

默认情况下,每个按钮单击都应该为每个CPU核心生成一个线程。但是,您可以强制执行自己的线程池大小。添加.NumTasks(1)调用并检查内存消耗,然后将其签入.NumTasks(10)并再次执行。如果在那之后,内存消耗会增长大约十倍,那么就是它了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36711681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档