iOS5.0.1 上的内存泄漏drawInRect
我有以下代码片段,用于缩放图像。这是一个为每次传递创建和耗尽自动释放池的循环。此代码在 iOS5.0 的模拟器、iPad 上的 iOS4.3 或模拟器中运行良好,但在 iPad1 上的 iOS5.0.1 上,经过 50-60 次后,drawInRect 开始消耗永远不会释放的内存。我一直从辅助线程调用它,但现在在主线程上调用缩放操作。
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
我做错了什么还是这是iOS5.0.1的错误?
更新: 我已经尝试了很多测试。我已经能够证明用 XCode 4.0 编译的完全相同的代码在同一台 iPad 上运行良好。使用 XCode 4.2.1 编译的相同代码会导致内存不足的情况。 该缩放例程正在后台线程中调用。我使用较低级别的核心图形调用编写了不同的缩放例程。它不会在 XCode 4.0 中泄漏,但在我的应用程序中使用 XCode 4.2.1 时会泄漏。在独立项目中运行的完全相同的例程和调用树在 XCode 4.2.1 上似乎不会泄漏(太多)内存。 我正在等待苹果公司对此的回应。同时,我需要使用 XCode 4。我唯一的安装映像需要 Snow Leopard,这意味着我正在使用我的 5.5 年前的老机器。 感谢
更新 1/2012 似乎只有当应用程序从 XCode 中启动时才会发生这种情况。在 iPad 上启动的相同可执行文件没有表现出泄漏。具有相同例程的不同应用程序不会出现泄漏。
我已经向 Apple 提交了一份错误报告,并向他们发送了一个重现该问题的项目。我预计这个问题不会很快得到解决,但它似乎并不像我最初想象的那么普遍。
更新 6/2012 尽管向苹果发送了一个重现该问题的最小项目,但他们声称无法重现该问题,并且没有取得任何进展。
I have the following code fragment that I use to scale images. This is in a loop that creates and drains an autorelease pool for each pass. This code works fine in the simulator in iOS5.0, in iOS4.3 on iPad or simulator, but on iOS5.0.1 on an iPad1, after 50-60 passes, drawInRect starts consuming memory that never gets released. I had been calling this from a secondary thread, but now invoke the scaling operations on the main thread.
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Am I doing something wrong or is this an iOS5.0.1 bug?
Update:
I've tried many tests. I have been able to prove that the exact same code compiled with XCode 4.0 runs fine on the same iPad. Same code compiled with XCode 4.2.1 causes an out of memory condition.
This scaling routine is being invoked in a background thread. I wrote a different scaling routine using lower level core graphics calls. It doesn't leak with XCode 4.0 but does leak when in my application with XCode 4.2.1. The exact same routine and invocation tree run in a stand alone project does not appear to leak (much) memory on XCode 4.2.1.
I'm waiting to hear from Apple on this one. In the mean time I need to use XCode 4. The only install image I have requires Snow Leopard which means I'm using my ancient 5.5 yr old machine.
Thanks
Update 1/2012
This only seems to occur if the app is started from within XCode. Same executable started on the iPad does no exhibit the leak. A different app with the same routine does not exhibit the leak.
I've opened a bug report with Apple and have sent them a project which reproduces the problem. I don't expect it to be resolved anytime soon, but it doesn't seem as pervasive as I originally thought.
Update 6/2012
Despite having sent Apple a minimal project which reproduced the problem, they claim not to be able to reproduce the problem and are not making any progress on it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信我终于找到了内存泄漏的原因。
我在执行一些核心数据插入时发现了类似的行为。循环,创建许多被释放的对象。当在 iPad 上运行时,内存使用量会上升,尽管没有明显的泄漏,直到应用程序内存不足而崩溃。但当从设备启动时,它运行没有问题。
我突然想到这与它从 Xcode 启动的方式有关。必须是项目中的调试设置。
事实证明,问题是由于调试时使用
NSZombieEnabled
引起的。要在 Xcode 4 中禁用此设置,请右键单击方案,即 app>targetDevice,编辑方案,选择“调试操作”、“参数”选项卡。要启用 NSZombieEnabled,需要使用该名称创建一个值为 YES 的环境变量,然后启用该变量。要禁用它,请取消选中该复选框。NSZombieEnabled
用于确定是否尝试释放已经释放的对象。为此,环境会跟踪所有已释放的对象。这会消耗内存,表现为内存泄漏。禁用此功能后,我的应用程序在 iPad1 上被杀死之前曾经快速增长超过 115MB,现在很高兴地保持在 24MB,没有内存泄漏。
I believe I have FINALLY found the cause of the memory leak.
I discovered similar behavior when doing some Core Data inserts. Looping, creating many objects that are released. When run on iPad, memory usage goes up although no leak is evident until the app crashes out of memory. But when initiated from the device, it runs without a problem.
It occurred to me that its something about the way its being started from Xcode. Must be a debug setting in the project.
Turns out the problem was caused by having
NSZombieEnabled
while debugging. To disable this setting in Xcode 4, right click on the schemes, ie app>targetDevice, edit the scheme, select the Debug action, arguments tab. To enableNSZombieEnabled
, an environment variable is created with that name with a value of YES and the variable is enabled. To disable it, uncheck the checkbox.NSZombieEnabled
is used to determine if you attempt to release an object that has already been released. To do this, the environment is keeping track of all released objects. This is consuming memory which appears as a memory leak.Once I disabled this, my app that used to quickly grow over 115MB before being killed on an iPad1 now happily sits at 24MB with no memory leak.
您发布的代码不应导致泄漏。泄漏肯定是在其他地方。
我建议执行以下两个步骤:
The code you posted shouldn't be causing leaks. The leak is definitely somewhere else.
I would recommend the following two steps: