Xcode Mac Cocoa:Can';t释放窗口以恢复其内存

Xcode Mac Cocoa:Can';t释放窗口以恢复其内存,xcode,macos,cocoa,malloc,nswindow,Xcode,Macos,Cocoa,Malloc,Nswindow,我有一个用Cocoa和ARC编写的应用程序,它允许用户创建和打开新窗口。(它类似于文档模型,但我不使用nsdocument。) 每一个新窗口都需要大量内存,如果用户关闭窗口,我希望能够获得这些内存 我知道[window close]只是隐藏窗口,但我也在使用[[self window]setReleasedWhenClosed:YES],但是NSwindowcontroller及其窗口在关闭后仍然存在 我的窗口的xib文件中的对象包含许多用malloc分配的大型c数组,因此我还尝试通过向wind

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

每一个新窗口都需要大量内存,如果用户关闭窗口,我希望能够获得这些内存

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

我的窗口的xib文件中的对象包含许多用malloc分配的大型c数组,因此我还尝试通过向windowcontroller的
windowWillClose:
方法中的通知中心发送调用来释放它们,其中,通知调用相关对象内的方法,以在窗口关闭之前释放C数组。同样,这是无效的——根据Activity Monitor的说法,即使调用了试图释放数组的方法并且显然释放了数组,也不会释放内存。我也尝试过释放
-(void)dealloc
中的数组,但这似乎从来没有在结束时调用过

那么,当窗口关闭时,如何才能最好地恢复内存

编辑:根据Benoit的评论

但是,对于由窗口控制器拥有的窗口,关闭时释放将被忽略


这是真的吗?如果是这样的话,我如何在ARC中解决这个问题?

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

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

建议:只要您的窗口被释放,请忽略活动监视器中的统计信息。你可以用仪器检查是否有泄漏

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


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

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

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

建议:只要您的窗口被释放,请忽略活动监视器中的统计信息。你可以用仪器检查是否有泄漏

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


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

谢谢,但我不确定我的2009 macbook是否强大到足以运行仪器。我发现它口吃,并将笔记本电脑风扇送入overdrive(超速档)约10分钟,监视一个窗口的打开情况,仪器不运行时通常需要5秒钟。@ChristianJ.B.:嗯,这很有趣。我2005年的mac电脑运行得很好……如果有帮助的话,我正在运行Instruments->leaks。@ChristianJ.B.:作为一个“穷人的检漏器”,你可以打开和关闭几个窗口,测量内存使用情况,然后打开和关闭更多的窗口(但不能同时打开更多的窗口)。如果在你打开和关闭窗口的过程中,内存使用量持续上升,那么你就有漏洞了。@ChristianJ.B:如果你不能运行仪器,那么我不知道该说什么。试着问一个问题