objective-c - cocoa 64 位二进制文​​件泄漏内存? (释放 NSData 不会释放内存)

标签 objective-c cocoa memory-leaks 64-bit nsdata

我一直在尝试不同版本的应用程序,似乎发生了一些奇怪的事情:

我的应用有 5mb 的闲置占用空间。上传文件时,文件大小的内存被保留。上传后保留的内存应该被释放。现在构建有所不同(gc = 垃圾收集器):

  • 32 位 i386 无 GC:立即释放所有内存。
  • 32 位 i386 GC:几乎所有内存都立即释放。稍后休息。
  • 64 位 x86_64 无 GC:释放的内存最少。像 10%
  • 64 位 x86_64 GC:根本没有释放任何内存。内存会保留数小时。 (事件周一)

我正在将 LLVM 与 CLANG 结合使用。我一直在运行今天的仪器,并检查泄漏/僵尸/等。一切似乎都很干净。 (该应用程序相当简单。)

是否有对此行为的解释?


更新:

这是一些奇怪的东西。我把问题归结为:

我将一个 20mb 的文件加载到 NSData 中并释放它。我在没有启用任何垃圾收集的情况下这样做。代码是:

NSData *bla = [[NSData alloc] initWithContentsOfFile:@"/bigshit"];
[bla release];

当我为 i386 32 位构建时,分配并释放了 20mb。当我将构建切换到 64 位 x86_64 时,该版本什么也不做。 20mb 保持分配状态。

upper pic 32bit lower 64 http://kttns.org/zguxn

除了上一个是为 32 位构建的而下一个是为 64 位构建的,这两个应用程序之间没有区别。没有 GC 在运行。 (启用 GC 后会出现同样的问题。)


更新 2:

当我仅使用 applicationDidFinishLaunching: 中的上层代码从头开始创建一个新的 Cocoa 应用程序时,可以观察到相同的行为。在 64 位模式下,内存不会被释放。 i386 按预期工作。

同样的问题出现在 NSString 而不是 NSData 上。当我启动 64 位内核时它也会出现。 (启动时保持 64。)

操作系统是 10.6.0

最佳答案

首先,使用Instrument的Object Graph工具验证内存不再被认为是在使用中;在某处没有保留计数或强引用。

如果它不再被使用,那么内存就会一直存在只是因为你没有达到收集器关心的阈值。

但是,这个声明:

64bit x86_64 no-GC: minimal memory is freed. like 10%

让我警惕。具体来说,如果您的代码设计为在非 GC 中工作——使用保留/释放——那么 (a) 您有内存泄漏,并且如果使用 CFRetain 或某种全局缓存,这可能会影响 GC 或 (b ) 你没有使用正确的工具来确定你是否有内存泄漏。

那么,您如何确定您正在泄漏内存?

更新;您正在使用事件监视器来监视进程的 RSIZE/VSIZE。这实际上不会告诉您任何有用的信息,除了“我的过程是否随着时间的推移而增长”。

很有可能(我没看过源代码),这段代码:

NSData *bla = [[NSData alloc] initWithContentsOfFile:@"/bigpoop"];

将导致 20MB 的文件被 mmap() 加载到进程中。根本不涉及 malloc() 样式分配。相反,操作系统将 20MB 的连续地址空间交给您的进程,并将文件的内容映射到其中。当您读取 NSData 的内容时,它会在您读取文件时出现页面错误。

当您释放 bla 时,映射将被销毁。但这并不意味着 VM 子系统会将应用程序的地址空间减少 20MB。

因此,您正在消耗大量地址空间,而不是实际内存。由于您的进程是 64 位的,地址空间几乎是无限的资源,使用地址的成本非常低,这就是操作系统以这种方式实现的原因。

即没有泄漏,您的应用程序运行正常,无论是否有 GC。

这是一个常见的误解,因此给这个问题加了星标。

关于objective-c - cocoa 64 位二进制文​​件泄漏内存? (释放 NSData 不会释放内存),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1383642/

相关文章:

cocoa - 同时打开多个文档,每个文档都有不同的菜单项状态

Java: "used memory"图处频繁出现峰值

python - 在 select 语句后提交时 pyodbc 内存泄漏

在循环中调用 pthread_cancel() 显示内存使用量增加

ios - 如何调用 -(void)update :(CCTime)delta method in Objective-C

objective-c - 将 App Delegate 连接到 Controller 类

objective-c - 将控件/按钮栏添加到配置为源列表的 NSOutlineView 的底部

objective-c - 如何处理来自 NSCollectionView 的按钮点击

ios - 在不使用全局变量和类的情况下在 IOS 中进行开发

objective-c - 是否可以制作没有圆边的 UITextField?