Memory leaks GCD调度\u异步内存泄漏?

Memory leaks GCD调度\u异步内存泄漏?,memory-leaks,grand-central-dispatch,dispatch-async,libdispatch,Memory Leaks,Grand Central Dispatch,Dispatch Async,Libdispatch,以下代码将占用约410MB内存,不会再次释放。(使用dispatch\u sync而不是dispatch\u async的版本将需要~8MB内存) 我预计会有一个高内存使用率高峰,但它应该会再次下降。。。漏洞在哪里 int main(int argc, const char * argv[]) { @autoreleasepool { for (int i = 0; i < 100000; i++) { dispatch_async(dispatch_get_glo

以下代码将占用约410MB内存,不会再次释放。(使用
dispatch\u sync
而不是
dispatch\u 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;
}  
int main(int argc,const char*argv[]{
@自动释放池{
对于(int i=0;i<100000;i++){
调度异步(调度获取全局队列(QOS类实用程序,0)^{
NSLog(“测试”);
});
}
NSLog(@“等待”);
[[NSRunLoop main runloop]rununteldate:[NSDate datewithtimeintervalcessincenow:60];
}
返回0;
}  
我试过:

  • 在循环周围和内部添加@autoreleasepool
  • 向循环中添加
    nsrunlop run
我尝试了几种组合,但从未看到内存减少(即使在等待几分钟后)。 我知道GCD参考指南包含以下声明:

尽管GCD调度队列有自己的自动释放池,但它们不保证这些池何时被排空


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

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

如果将“异步”更改为“同步”,则在上一个块完成并销毁后,将创建下一个块对象

UPD

关于GCD池

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

从文件:

--

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

--

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

您可以阅读有关GCD线程池的最大计数的信息


我在Alocations profiler中看到,有许多NSThread被分配而没有被破坏。我认为这是系统池,必要时将被释放

在每次GCD呼叫中始终放置@autoreleasepool,您将不会遇到任何问题。我也有同样的问题,这是唯一的解决办法

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), ^{
        // everything INSIDE in an @autoreleasepool
        @autoreleasepool {
          NSLog(@"test");
        }
      });
    }
    NSLog(@"Waiting.");
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
  }
  return 0;
}  
int main(int argc,const char*argv[]{
@自动释放池{
对于(int i=0;i<100000;i++){
调度异步(调度获取全局队列(QOS类实用程序,0)^{
//@autoreleasepool中的所有内容
@自动释放池{
NSLog(“测试”);
}
});
}
NSLog(@“等待”);
[[NSRunLoop main runloop]rununteldate:[NSDate datewithtimeintervalcessincenow:60];
}
返回0;
}  

没错,但这不是问题的答案。所有块完成后,内存使用率应再次下降(至少)。但事实并非如此。高内存使用率的峰值是非常好的。