iPhone 应用程序正在泄漏内存; Instruments 和 Clang 找不到泄漏点
我开发了一个iPhone程序,它是一种图像处理程序:
用户获得一个UIImagePickerController并选择一个图像。然后程序在新线程中进行一些繁重的计算(为了应用程序的响应能力)。当然,线程有自己的自动释放池。计算完成后,独立线程向主线程发出信号,表明可以呈现结果。该应用程序创建一个新的视图控制器,并将其推送到导航控制器上。
简而言之:
- UIImagePickerController
- 新线程(自动释放池)使用图像数据
- 向主线程发出信号进行一些繁重的计算,表明它已完成
- 主线程创建视图控制器并将其推送到导航控制器
- 视图控制器呈现图像结果
我的程序运行良好,但如果我忽略通过点击后退按钮并重复整个过程多次,我的应用程序崩溃了。但仅限于设备上! Instruments 找不到任何泄漏(除了一些我不认为负责的小泄漏:线程创建、NSCFString;总体大约 10 kB)。甚至 Clang 静态分析器也告诉我,我的代码似乎没问题。
我知道 UIImage 类可以缓存从便捷方法返回的图像和对象,只有当它们的自动释放池耗尽时才会被释放。但大多数时候我使用 CGImageRef 并使用 UIImage' alloc, init &尽快释放内存的方法。
目前,我不知道如何隔离问题。您将如何解决这个问题?
Crash Log:
Incident Identifier: F4C202C9-1338-48FC-80AD-46248E6C7154
CrashReporter Key: bb6f526d8b9bb680f25ea8e93bb071566ccf1776
OS Version: iPhone OS 3.1.1 (7C145)
Date: 2009-09-26 14:18:57 +0200
Free pages: 372
Wired pages: 7754
Purgeable pages: 0
Largest process: _MY_APP_
Processes
Name UUID Count resident pages
_MY_APP_ <032690e5a9b396058418d183480a9ab3> 17766 (jettisoned) (active)
debugserver <ec29691560aa0e2994f82f822181bffd> 107
syslog_relay <21e13fa2b777218bdb93982e23fb65d3> 62
notification_pro <8a7725017106a28b545fd13ed58bf98c> 64
notification_pro <8a7725017106a28b545fd13ed58bf98c> 64
afcd <98b45027fbb1350977bf1ca313dee527> 65
mediaserverd <eb8fe997a752407bea573cd3adf568d3> 319
ptpd <b17af9cf6c4ad16a557d6377378e8a1e> 142
syslogd <ec8a5bc4483638539fa1266363dee8b8> 68
BTServer <1bb74831f93b1d07c48fb46cc31c15da> 119
apsd <a639ba83e666cc1d539223923ce59581> 165
notifyd <2ed3a1166da84d8d8868e64d549cae9d> 101
CommCenter <f4239480a623fb1c35fa6c725f75b166> 161
SpringBoard <8919df8091fdfab94d9ae05f513c0ce5> 2681 (active)
accessoryd <b66bcf6e77c3ee740c6a017f54226200> 90
configd <41e9d763e71dc0eda19b0afec1daee1d> 275
fairplayd <cdce5393153c3d69d23c05de1d492bd4> 108
mDNSResponder <f3ef7a6b24d4f203ed147f476385ec53> 103
lockdownd <6543492543ad16ff0707a46e512944ff> 297
launchd <73ce695fee09fc37dd70b1378af1c818> 71
**End**
i've developed an iPhone program which is kind of an image manipulation program:
The user get an UIImagePickerController and selects an image. Then the program does some heavy calculating in a new thread (for responsiveness of the application). The thread has, of course, its own autorelease pool. When calculation is done, the seperated thread signals the main thread that the result can be presented. The app creates a new view controller, pushes it onto the navigation controller.
In short:
- UIImagePickerController
- new thread (autorelease pool) does some heavy calculation with image data
- signal to main thread that it's done
- main thread creates view controller and pushes it onto navigation controller
- view controller presents image result
My program works well, but if I dismiss the navigation controller's top view controller by tapping on the back button and repeat the whole process several times, my app crashes. But only on the device!
Instruments cannot find any leaks (except for some minor ones which I don't feel responsible for: thread creation, NSCFString; overall about 10 kB). Even Clang static analyzer tells me that my code seems to be all right.
I know that the UIImage class can cache images and objects returned from convenience methods get freed only whet their autorelease pool gets drained. But most of the time I work with CGImageRef and I use UIImage' alloc, init & release methods to free memory as soon as possible.
Currently, I don't know how to isolate the problem. How would you approach this problem?
Crash Log:
Incident Identifier: F4C202C9-1338-48FC-80AD-46248E6C7154
CrashReporter Key: bb6f526d8b9bb680f25ea8e93bb071566ccf1776
OS Version: iPhone OS 3.1.1 (7C145)
Date: 2009-09-26 14:18:57 +0200
Free pages: 372
Wired pages: 7754
Purgeable pages: 0
Largest process: _MY_APP_
Processes
Name UUID Count resident pages
_MY_APP_ <032690e5a9b396058418d183480a9ab3> 17766 (jettisoned) (active)
debugserver <ec29691560aa0e2994f82f822181bffd> 107
syslog_relay <21e13fa2b777218bdb93982e23fb65d3> 62
notification_pro <8a7725017106a28b545fd13ed58bf98c> 64
notification_pro <8a7725017106a28b545fd13ed58bf98c> 64
afcd <98b45027fbb1350977bf1ca313dee527> 65
mediaserverd <eb8fe997a752407bea573cd3adf568d3> 319
ptpd <b17af9cf6c4ad16a557d6377378e8a1e> 142
syslogd <ec8a5bc4483638539fa1266363dee8b8> 68
BTServer <1bb74831f93b1d07c48fb46cc31c15da> 119
apsd <a639ba83e666cc1d539223923ce59581> 165
notifyd <2ed3a1166da84d8d8868e64d549cae9d> 101
CommCenter <f4239480a623fb1c35fa6c725f75b166> 161
SpringBoard <8919df8091fdfab94d9ae05f513c0ce5> 2681 (active)
accessoryd <b66bcf6e77c3ee740c6a017f54226200> 90
configd <41e9d763e71dc0eda19b0afec1daee1d> 275
fairplayd <cdce5393153c3d69d23c05de1d492bd4> 108
mDNSResponder <f3ef7a6b24d4f203ed147f476385ec53> 103
lockdownd <6543492543ad16ff0707a46e512944ff> 297
launchd <73ce695fee09fc37dd70b1378af1c818> 71
**End**
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否正在捕获并处理内存警告?您的代码可能使用了太多内存。尝试在视图控制器中使用
-(void)didReceiveMemoryWarning
方法来查看它是否被调用。此行为与您所看到的一致,因为 iPhone 设备的内存量非常有限,但 iPhone 模拟器仅受计算机中 RAM 的限制。
Are you catching and handling memory warnings? Your code could just be using too much memory. Try using the
-(void)didReceiveMemoryWarning
method in a view controller to see if it's getting called.This behavior would be consistent with what you're seeing, since the iPhone device has a very limited amount of memory, but the iPhone simulator is limited only by the RAM in your computer.
我注释掉了一些行,并围绕某些代码片段构建了一些繁重的 for 循环来隔离和查找问题。事实证明,我在一个较小的方法中删除了一行,该方法本应在计算后清除:
因此,在生成新图像时,旧结果被泄露。
我想知道为什么 Clang 或 Instruments 没有发现这个泄漏。但感谢您的帮助!
I commented out some lines and build some heavy for-loops around certain code fragments to isolate and find the problem. It turned out that I have deleted a line in a smaller method which was supposed to clear up after the computation:
So when generating a new image, the old result got leaked.
I wonder why Clang or Instuments didn't find this leak. But thanks for your help!
“泄漏”是指泄漏工具吗?这可能不会“看到”您的 CG 调用消耗的内存为泄漏,因为它们是 malloced...
您使用 ObjectAlloc 会好很多倍,并查看在短时间内保留了哪些内存(将其拖过时间线,按住选项可以查看一小部分时间)。
By "Leak", do you mean the instruments Leak tool? That may not "see" the memory consumed by your CG calls as leaks because they are malloced...
You are many times better off using ObjectAlloc, and looking at what memory is being held onto there in a short time period (drag across the timeline with option held down to see a small region of time).