0

我有一个使用 ARC 用 Cocoa 编写的应用程序,它允许用户创建和打开新窗口。(它就像一个文档模型,但我没有使用 nsdocument。

每个新窗口都需要大量内存,如果用户关闭窗口,我想取回这些内存。

我知道这[window close]只是隐藏了窗口,但我也在使用[[self window] setReleasedWhenClosed:YES],但NSwindowcontroller关闭后它及其窗口仍然存在。

我窗口的 xib 文件中的对象包含许多用 malloc 分配的大型 c 数组,因此我还尝试通过向 windowcontrollerwindowWillClose:方法内的通知中心发送调用来释放它们,其中通知调用相关对象内的方法来在窗口关闭之前释放 C 数组。同样,这是没有效果的——即使尝试释放数组的方法被调用并且数组显然被释放,根据活动监视器,没有内存被释放。我也尝试过释放 中的数组-(void) dealloc,但这似乎从来没有在关闭时被调用过。

那么,当窗口关闭时,我怎样才能最好地恢复内存呢?

编辑:根据Benoit对此 stackoverflow 页面的评论,

“但是,窗口控制器拥有的窗口会忽略关闭时的释放。”

真的吗?如果是这样,我怎样才能在 ARC 中解决这个问题?

4

1 回答 1

3

释放的内存不能总是返回给操作系统。这只是生活中的事实,至少在没有压缩垃圾收集器的系统上是这样。

除非您确切知道自己在看什么,否则不要关注活动监视器中的统计信息。除非您对系统有相当透彻的了解,否则这些信息通常没有用处——包括虚拟内存、共享库占用的内存部分以及您正在使用的分配器的行为。NSArray和类在NSMutableArray分配方面有一些相当不透明的行为,它们通常不是顾名思义的线性数组。

建议:只要你的窗口被释放,忽略Activity Monitor中的统计信息。您可以使用仪器来检查泄漏。

举个为什么应该忽略 Activity Monitor 的例子:如果你在 1 KiB 块中分配 500 MiB,然后释放奇数块,显然它们不能返回给操作系统,因为页面粒度是 4大多数现代系统上的 KiB 最小值。如果您在 1 MiB 块中分配相同的 500 MiB 并释放奇数块,它们将返回给操作系统,并且内存使用量将减少 250 MiB,如 Activity Monitor 报告的那样。(请注意,4 KiB 阈值不是发生此行为的阈值。它取决于 的确切分配行为malloc(),以及在 OS X 上取决于 CPU 和 RAM 量的一些参数。)

但是,这可能无关紧要。在每种情况下,如果您再次分配 250 MiB,您将回到开始的位置。使用较少的私有内存很好,但这只会影响您的应用程序与其他应用程序的运行情况。

于 2012-11-23T01:31:20.090 回答