我的应用程序有一个5mb的闲置足迹.当上传文件大小的文件内存被保留时.上传后,保留的内存应该被释放.现在在构建中有差异(gc =垃圾收集器):
> 32bit i386 no-GC:所有内存都可以立即释放.
> 32bit i386 GC:几乎所有的内存都可以立即释放.其余一段时间后.
> 64bit x86_64 no-GC:最小内存被释放.像10%
> 64bit x86_64 GC:没有任何内存被释放.内存保留数小时. (活动单)
我正在使用LLVM与CLANG.我一直在运行仪器,并检查泄漏/僵尸等.一切似乎都很干净. (应用程序相当简单)
这个行为有解释吗?
更新:
这是一些奇怪的东西.我已经将问题解决了:
我将一个20mb的文件加载到NSData中并释放它.我这样做没有任何垃圾收集启用.代码是:
NSData *bla = [[NSData alloc] initWithContentsOffile:@"/bigshit"];[bla release];
当我为i386 32bit构建时,20mb被分配和发布.当我将构建转换为64位x86_64时,发行版什么都不做. 20mb分配.
upper pic 32bit lower 64 http://kttns.org/zguxn
这两个应用程序没有区别,除了上面的一个是为32位构建,较低的一个为64位.没有GC运行. (启用GC启用相同的问题.)
更新2:
当我从头开始创建新的可可应用程序时,只能使用applicationDIDFinishLaunching:中的上一个代码,就可以观察到相同的行为.在64位模式下,内存不会释放. i386按预期工作.
Nsstring而不是NSData出现同样的问题.当我启动64位内核时也会出现. (启动时持有64名)
*** 作系统是10.6.0
解决方法@H_301_46@ 首先,使用仪器的对象图仪器来验证内存不再被视为使用;在某处没有保留计数或强参考.如果它不再使用,那么内存就是因为你没有达到收藏者所关心的门槛所在.
但是,这个说法:
64bit x86_64 no-GC: minimal memory is
freed. like 10%
让我很警惕具体来说,如果您的代码被设计为在非GC中使用retain / release,那么(a)您有内存泄漏,如果使用CFRetain或某种全局缓存,可能会影响GC或(b )你没有使用正确的工具来弄清楚你是否有内存泄漏.
那么,你如何确定你正在泄漏记忆?
更新;您正在使用Activity Monitor来监视进程的RSIZE / VSIZE.这实际上不会告诉你任何有用的东西,“我的过程随着时间的推移而增长”.
更有可能(我没看过来源),这段代码:
NSData *bla = [[NSData alloc] initWithContentsOffile:@"/bigpoop"];
将导致20MB文件为mmap()’.根本没有涉及到malloc()风格分配.相反, *** 作系统将20MB的连续地址空间交给您的进程,并将文件的内容映射到其中.当您读取NSData的内容时,它会在文件中出现页面错误.
当你释放bla时,映射被破坏.但这并不意味着VM子系统将减少20MB的应用程序的地址空间.
所以,你正在燃烧一堆地址空间,而不是实际的内存.由于您的进程是64位,因此地址空间几乎是一个无限的资源,使用地址的成本非常低,所以 *** 作系统以这种方式实现的原因.
即没有泄漏,您的应用程序的行为正确,GC或否.
这是一个常见的误解,因此,这是一个问题.
总结以上是内存溢出为你收集整理的objective-c – 可可64位二进制文件泄漏记忆? (释放NSData不释放内存)全部内容,希望文章能够帮你解决objective-c – 可可64位二进制文件泄漏记忆? (释放NSData不释放内存)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)