GCD dispatch_async内存泄漏?

And*_*eas 9 memory-leaks libdispatch grand-central-dispatch dispatch-async

以下代码将占用~410MB的内存,不会再次释放.(使用的版本dispatch_sync代替dispatch_async将需要~8MB内存)
我预计会有高内存使用率的飙升,但它应该再次下降......泄漏在哪里?

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    for (int i = 0; i < 100000; i++) {
      dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
        NSLog(@"test");
      });
    }
    NSLog(@"Waiting.");
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
  }
  return 0;
}  
Run Code Online (Sandbox Code Playgroud)

我试过了:

  • 在循环内部和内部添加@autoreleasepool
  • 添加NSRunLoop run循环

我尝试了几种组合,从未看到内存减少(即使在等待几分钟后).我知道GCD参考指南,其中包含以下声明:

尽管GCD调度队列具有自己的自动释放池,但它们无法保证这些池何时耗尽.

这段代码中是否有内存泄漏?如果没有,有没有办法强制队列释放/排出已完成的块?

And*_*nov 1

Objective-C 块是一个 C 结构,我认为您创建了 100000 个块对象来在后台线程中执行它们,并且它们等待系统可以运行它们。您的设备可以执行有限数量的线程,这意味着许多块将在操作系统启动它们之前等待。

\n\n

如果将“async”更改为“sync”,则在前一个块完成并销毁后,将创建下一个块对象。

\n\n

UPD

\n\n

关于GCD池。

\n\n

GCD在GCD线程池上执行任务,线程由系统创建,并由系统管理。系统缓存线程以节省CPU时间,每个调度任务都在空闲线程上执行。

\n\n

来自文档:

\n\n

\xe2\x80\x94\xe2\x80\x94

\n\n

提交到调度队列的块在完全由系统管理的线程池上执行。不保证执行任务的线程。

\n\n

\xe2\x80\x94\xe2\x80\x94

\n\n

如果您将任务作为同步任务运行,则在当前任务\xe2\x80\x99s完成后,存在空闲线程(来自GCD线程池)来执行下一个任务(因为主线程在任务执行时正在等待,并且不会添加新的任务)任务到队列中),并且系统不会分配新的 NSThread (在我的 mac 上,我\xe2\x80\x99见过 2 个线程)。如果你以异步方式运行任务,那么系统可以分配许多 NSThreads(为了实现最大性能,在我的 mac 上它接近 67 个线程),因为全局队列包含许多任务。

\n\n

在这里您可以了解 GCD 线程池的最大数量。

\n\n

我\xe2\x80\x99在分配分析器中看到有许多NSThreads被分配但没有被破坏。我认为这是系统池,如果需要的话将被释放。

\n