gpt4 book ai didi

memory-leaks - GCD dispatch_async 内存泄漏?

转载 作者:行者123 更新时间:2023-12-04 04:38:11 25 4
gpt4 key购买 nike

以下代码将占用~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;
}

我试过:
  • 在循环周围和内部添加@autoreleasepool
  • 添加 NSRunLoop run到循环

  • 我尝试了几种组合,但从未看到内存减少(即使在等待几分钟后)。
    我知道 GCD 引用指南包含以下声明:

    Although GCD dispatch queues have their own autorelease pools, they make no guarantees as to when those pools are drained.



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

    最佳答案

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

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

    UPD

    关于 GCD 池。

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

    从文档:

    ——

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

    ——

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

    Here您可以阅读 GCD 线程池的最大计数。

    我在 Alocations profiler 中看到有很多 NSThreads 被分配但没有被破坏。我认为这是系统池,如有必要将被释放。

    关于memory-leaks - GCD dispatch_async 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28537660/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com