在我将iPad更新到iOS9之后,我的代码中出现了内存泄漏,这在iOS8和iOS7上运行良好。
我有一个由以下代码创建的匿名线程:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[self threadWork];
});
并且该线程执行了一对malloc / free调用:
- (void)threadWork {
// Create a serial queue.
dispatch_queue_t mySerialQueue = dispatch_queue_create("myQueue", NULL);
while (1) {
// Do a simple malloc.
int *foo = (int *)malloc(1024);
// Do free in serial queue.
dispatch_async(mySerialQueue, ^{
free(foo);
});
[NSThread sleepForTimeInterval:1.0 / 60.0];
}
}
此路由将增加内存使用量并最终崩溃iOS 9上的设备。在Objective-C ++中新问题/删除也会出现问题。
我发现了其他一些没有内存泄漏的方法:
我不明白为什么这个简单的路由会导致这个问题。 我在谷歌上搜索了这个,但一无所获。
如何保留串行队列和GCD匿名线程?
更新
我试图在我的代码中放置NSLog命令,以确定何时调用malloc / free。结果表明,它们都被立即调用并成对出现。我也尝试将线程减慢到每秒一次,但问题仍然存在。
线程的测试代码:
- (void)threadWork {
uint64_t mallocCount = 0;
__block uint64_t freeCount = 0;
dispatch_queue_t mySerialQueue = dispatch_queue_create("MyQueue", NULL);
while (1) {
void *test = malloc(1024);
NSLog(@"malloc %llu", ++mallocCount);
dispatch_async(mySerialQueue, ^{
free(test);
NSLog(@"free %llu", ++freeCount);
});
[NSThread sleepForTimeInterval:1.0];
}
}
控制台结果:
...
2015-10-23 09:51:33.876 OS9MemoryTest[759:153135] malloc 220
2015-10-23 09:51:33.876 OS9MemoryTest[759:153133] free 220
2015-10-23 09:51:34.877 OS9MemoryTest[759:153135] malloc 221
2015-10-23 09:51:34.878 OS9MemoryTest[759:153133] free 221
2015-10-23 09:51:35.883 OS9MemoryTest[759:153135] malloc 222
2015-10-23 09:51:35.883 OS9MemoryTest[759:153133] free 222
答案 0 :(得分:1)
我认为我找到了一种更好的方法来做到这一点,而不是使用dispatch_sync。
这一点似乎是串行队列的服务质量(QoS)类的设置。 在具有QOS_CLASS_UNSPECIFIED QoS类的队列中空闲会导致此问题。
在我的问题中,我释放了一个由以下调用创建的串行队列中的内存:
dispatch_queue_t mySerialQueue = dispatch_queue_create("MyQueue", NULL);
其QoS设置为QOS_CLASS_UNSPECIFIED,导致此问题。
如果创建一个带有dispatch_queue_attr_t对象的串行队列,其QoS设置不包括QOS_CLASS_UNSPECIFIED,则代码运行完美而不会泄漏:
- (void)threadWork {
// Create a serial queue with QoS class.
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
dispatch_queue_t mySerialQueue = dispatch_queue_create("myQueue", attr);
while (1) {
// Do a simple malloc.
int *foo = (int *)malloc(1024);
// Do free in serial queue.
dispatch_async(mySerialQueue, ^{
free(foo);
});
[NSThread sleepForTimeInterval:1.0 / 60.0];
}
}
我仍然不明白为什么在iOS9上会出现这个问题, 但设置QoS似乎可以使事情发挥作用。