我遇到了一个我似乎无法弄清楚的问题。进行了大量搜索,并尝试了大约 50 种不同的变体,但到目前为止还没有成功。这是我的困境。
我有 3 种方法。一个在我的 PageView 对象加载时调用,另一个在用户进行更改时调用,最后一个在用户离开页面时调用。
第一种方法:
- (void)captureInitialLinesTexture {
@autoreleasepool {
self.initialLinesTextureCaptured = TRUE;
GLubyte *buffer =(GLubyte *) malloc (1024 * 1024 * 4 * sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT,1) ;
glReadPixels(0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindTexture(GL_TEXTURE_2D, [pageTexture name]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
NSData __autoreleasing *tempData = [NSData dataWithBytes:buffer length:1024*1024*4*sizeof(GLubyte)];
if (textureData == nil) {
textureData = [self.pageController.notebookDoc newTextureInPage:self.page];
}
[pageTextures addObject:tempData];
if ([pageTextures count] > 5) {
[pageTextures removeObjectAtIndex:0];
}
textureData.textureData = tempData;
textureData.page = self.page;
self.page.texture = textureData;
self.page.lastLineId = [NSNumber numberWithInt:self.pageController.newLineId - 1];
[self.pageController saveNotebookWithUndo:FALSE];
free((GLubyte*)buffer);
}
}
第二种方法:
-(void)capturePageTexture {
@autoreleasepool {
GLubyte *buffer =(GLubyte *) malloc (1024 * 1024 * 4 * sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT,1) ;
glReadPixels(0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
NSData __autoreleasing *tempData = [NSData dataWithBytes:buffer length:1024*1024*4*sizeof(GLubyte)];
[pageTextures addObject:tempData];
if ([pageTextures count] > 5) {
[pageTextures removeObjectAtIndex:0];
}
free((GLubyte*)buffer);
}
}
最后一个方法:
-(void)attemptInstantPageTextureCapture {
if ([pageTextures count] > 0) {
self.page.texture.textureData = [pageTextures lastObject];
self.page.lastLineId = [NSNumber numberWithInt:self.pageController.newLineId - 1];
[self.pageController saveNotebookWithUndo:FALSE];
}
[pageTextures removeAllObjects];
pageTextures = [NSMutableArray arrayWithCapacity:0];
}
我的问题是那些 NSData *tempData 变量。出于某种原因,其中一个在我的 PageView 消失后随机徘徊(通过 Allocations Instruments 发现)。
如果我加载 PageView,captureInitialLinesTexture 会触发。然后,我可以添加大量笔划,每次笔划后都会触发 capturePageTexture,在 NSMutableArray 名称 pageTextures 中保留最多 5 个 NSData 变量。当我离开 PageView 时,NSMutableArray 被清空。
现在这里是它用头撞墙的地方。 NSData 的分配大小始终相同,在本例中为 4mb。当页面加载时,我有 1 个 4mb 的分配。如果我画笔画,我最多可以再画 5 个。然后,当我离开 PageView 时,最多释放 4mb 分配(NSData)中的 5 个,但我总是只剩下 1 个。如果我随后转到仪器上的 Call Tree,它会随机地说它来自第一种方法或第二种方法方法。为什么转储存储在数组中的 5 个 NSData 没有问题,但由于某种原因 1 个 NSData 在某处还活着。此外,这个神秘的 NSData 随机来自任一方法。
就像我说的,我搜索了又搜索都找不到解决这个问题的办法。 4MB 的内存显然是巨大的,所以随着时间的推移,任何此类泄漏都会终止应用程序。
一次尝试的分配:
为该尝试调用树:
分配给另一次尝试:
为其他尝试调用树:
每次都会触发完全相同的代码,并且每次 NSData 保持事件状态都是随机的。任何人都知道我做错了什么?如果您想知道,“page”和“textureData”变量是 NSManagedObjects。就我尝试过的事情而言:
在 NSData 对象上分配,然后调用 initWithBytes:length:
initWithBytesNoCopy:Length: - 没有调用 free((GLubyte*)buffer);
initWithBytesNoCopy:Length:freeWhenDone: - 没有调用 free((GLubyte*)buffer);
以上两种尝试的NSData类方法版本
不使用@autoreleasepool
不使用 __autoreleasing 声明 var
使 NSMutableArray pageTextures 成为 PageView 的属性
在从 NavigationController 堆栈弹出之前将 PageView 设置为 nil
使用 __strong 遍历 pageTextures 可变数组并将所有 NSData 设置为 nil 或 null。
如上所述,这一切都发生在 PageView 类中,该类是 PageViewController 中的许多同类之一,被插入导航 Controller ,然后从导航 Controller 弹出。一旦 PageViewController(PageView 的唯一 super View )从导航堆栈中弹出,一个随机的 NSData 分配仍然有效。
任何建议都将不胜感激!至于上面提到的核心数据元素,代码完全按计划工作。唯一的问题是偷偷摸摸的实时 NSData 分配...:(
最佳答案
前一段时间解决了这个问题,但我想我会发布发生的事情,以防其他人遇到同样的问题。基本上,问题在于 NSData 对象被分配给核心数据实体,而核心数据控制着何时释放自己的内存。因此,虽然代码看起来不错,但核心数据仍然保留在 NSData 对象上,在它们超出范围并且运行循环完成之后(当 ARC 通常启动时)。
为了解决这个问题,我们只是将 NSData 保存到一个文件中,并更改了模型,以便核心数据实体只包含文件路径的字符串 (NSString) 而不是 bool 数据 (NSData)。
问题解决:)
关于objective-c - NSData 内存未释放 - ARC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10592922/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U
你好,我无法成功如何在散列中删除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
在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中
如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta
这会导致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