【发布时间】:2010-12-30 08:54:40
【问题描述】:
对不起,描述太长了,但是问题并不那么容易......
我在没有 GC 的情况下编写的项目。最近我发现了一个我找不到的内存泄漏。我确实使用了新的 Xcode Analyzer,但没有结果。我确实逐行阅读了我的代码并验证了所有 alloc/release/copy/autorelease/mutableCopy/retain 和 pools... - 仍然没有。
前言:由于某种原因,Standard Instruments 和 Omni Leak Checker 对我不起作用(Omin Tool 拒绝了我的应用程序,Instruments.app(Leaks)占用了太多内存和 CPU,所以我没有机会使用它)。
所以我想编写并使用我自己的代码来挂钩和跟踪“所有”alloc/allocWithZone:/dealloc 消息统计信息,以编写一些简单的自己的泄漏检查库(主要目标只是标记可能泄漏的对象的类名)。
我使用的主要挂钩技术:
Method originalAllocWithZone = class_getClassMethod([NSObject class],@selector(allocWithZone:));
if (originalAllocWithZone)
{
imp_azo = (t_impAZOriginal)method_getImplementation(originalAllocWithZone);
if (imp_azo)
{
Method hookedAllocWithZone = class_getClassMethod([NSObject class],@selector(hookedAllocWithZone:));
if (hookedAllocWithZone)
{
method_setImplementation(originalAllocWithZone,method_getImplementation(hookedAllocWithZone));
fprintf(stderr,"Leaks Hook: allocWithZone: ; Installed\n");
}
}
}
- 这样的代码钩住 alloc 方法,和 dealloc 作为 NSObject 类别方法。
我将 IMP 保存为以前的方法实现,然后注册并计算所有 alloc/allocWithZone:调用为增量 (+1) stat-array NSInteger 值,而 dealloc 调用为减量 (-1)。
作为终点,我调用之前的实现和返回值。
在概念上一切正常。
如果需要,我什至可以检测类何时是类集群的一部分(如 NSString、NSPathStore2;NSDate、__NSCFDate)...通过一些规范化功能(但对于下面描述的问题无关紧要)。
但是这种技术存在一些问题:
- 并非所有类都可以被捕获,因为 例如,[NSDate date] 没有捕捉到 在 alloc/allocWithZone: 但是,我可以在 GDB 中看到 alloc 调用
- 由于我尝试使用自动单例检测技术(基于retainCount readind)从最终统计信息中自动排除一些对象,当启动完整的Cocoa 应用程序(实际上,即使是简单的Objective-包含 Foundation 框架的 C 命令行实用程序在 main()) 之前有一些额外的初始化 - GDB 有 allocWithZone: 一个接一个地调用,....
在此处上传完整的概念项目草稿源:http://unclemif.com/external/DILeak.zip (3.5 Kb)
从 Terminal.app 运行 make 来编译它,运行 ./concept 来展示它。
第一个问题:为什么我不能通过挂钩 alloc 和 allocWithZone: 方法来捕获所有对象分配?
第二个问题:为什么挂钩 allocWithZone:某些类的 CFGetRetainCount(或 [inst retainCount])冻结...
【问题讨论】:
-
哇。避免使用明显的解决方案真的很远,因为它们太慢或使用太多内存,但是,有人想知道,当工具(无论您使用哪种工具)不被留下时,任何这样的论点是否有效在最终构建中,但仅在怀疑有问题时使用。我认为对于 99.999% 的人来说,使用标准工具是正确的答案,而使用自己的工具是一个奇怪的解决方案,很少有其他开发人员会觉得有用。
标签: objective-c cocoa memory memory-leaks objective-c++