我有兴趣详细了解如何使用 ARC 在紧密循环下最好地处理内存管理。特别是,我有一个我正在编写的应用程序,它有一个 while 循环,它运行了很长时间,而且我注意到尽管已经实现了(我认为是) ARC 中的最佳实践,堆会无限增长。
为了说明我遇到的问题,我首先将以下测试设置为故意失败:
while (true) {
NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
[array addObject:@"bar"]; // do something with it to prevent compiler optimisations from skipping over it entirely
}
运行此代码并使用分配工具进行分析表明内存使用量不断增加。然而,将它包装在一个 @autoreleasepool 中,如下所示,立即解决了问题并保持内存使用良好且低:
while (true) {
@autoreleasepool {
NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
[array addObject:@"bar"];
}
}
完美!这一切似乎都运行良好——甚至对于使用 [[... alloc] init] 创建的非自动释放实例,它甚至运行良好(正如预期的那样)。一切正常,直到我开始涉及任何 UIKit 类。
例如,让我们创建一个UIButton,看看会发生什么:
while (true) {
@autoreleasepool {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectZero;
}
}
现在,内存使用量会无限增加——实际上,@autoreleasepool 似乎没有任何效果。
所以问题是为什么@autoreleasepool 对NSMutableArray 工作正常并保持内存检查,但是当应用于UIButton 时 堆继续增长?
最重要的是,在像这样无限循环中使用 UIKit 类时,如何防止堆无限扩展,这告诉我们关于 while 中 ARC 的最佳实践(true) 或 while(keepRunningForALongTime) 样式循环?
我对此的直觉是(我可能完全错了)这可能是关于 while (true) 如何防止 runloop 循环,从而保持 UIKit 内存中的实例而不是释放它们......但显然我在理解 ARC 时遗漏了一些东西!
(为了消除明显的原因,NSZombiedEnabled 未启用。)
最佳答案
至于为什么 UI* 对象无限增长?内部实现细节。最有可能的是,您通过阻塞主运行循环有效地禁用了某种缓存或运行循环交互。
这让我得出了真正的答案:
Most importantly, how can I keep the heap from expanding endlessly when using UIKit classes in an endless loop like this, and what does this tell us about the best practices for ARC in while(true) or while(keepRunningForALongTime) style loops?
如何解决? 永远不要在主线程上使用紧密循环并且永远不要阻塞主运行循环。
即使您找出并解决了 UI* 引起的堆增长,如果您在主线程上使用 while(...) 循环,您的程序仍然无法运行. iOS 应用程序和 Cocoa 应用程序的整个设计是主线程有一个主运行循环,并且主运行循环必须可以自由运行。
如果不是呢?您的应用程序不会响应(并最终被系统杀死)用户输入并且您的绘图代码不太可能按预期工作(因为运行循环合并脏区域并根据需要与主线程一起绘制它们,通常卸载到辅助线程)。
关于iphone - ARC 下紧密循环中 UIKit 的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14304090/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
我想用这两种语言中的任何一种(最好是ruby)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生
你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p
这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什
这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源