0

I have an application written in Cocoa with ARC which allows the user to create and open new windows. (It's like a document model, but I'm not using nsdocument.)

Each new window requires a large amount of memory, which I would like to get back if the user closes the window.

I understand that [window close] simply hides the window, but I'm also using [[self window] setReleasedWhenClosed:YES], but both the NSwindowcontroller and its window are still in existence after the close.

The objects in my window's xib file contain a number of large c arrays allocated with malloc, so I've also tried freeing them by sending a call to the notification center inside the windowcontroller's windowWillClose: method, where the notification calls a method inside the relevant objects to free the C arrays before the window closes. Again, this is to no effect- even though the method attempting to free the arrays is called and the arrays are apparently freed, according to Activity Monitor, no memory is ever released. I've also tried freeing the arrays in -(void) dealloc, but this doesn't appear to ever be called upon a close.

So, how can I best get the memory back when a window is closed?

Edit: According to a comment on this stackoverflow page by Benoit,

"Release when closed, however, is ignored for windows owned by window controllers."

Is that true? If so, how can I get around that in ARC?

Community
  • 1
  • 1
Christian J. B.
  • 491
  • 1
  • 5
  • 16

1 Answers1

3

Memory released cannot always be returned to the operating system. This is just a fact of life, at least on systems that do not have compacting garbage collectors.

Do not pay attention to the statistics in Activity Monitor unless you know exactly what you're looking at. The information is not generally useful unless you have fairly thorough knowledge of the system — including virtual memory, what part of your memory is taken up by shared libraries, and the behavior of the allocator you are using. The NSArray and NSMutableArray classes have some fairly opaque behavior when it comes to allocations, they are generally not linear arrays as the name suggests.

Suggestion: As long as your window is freed, ignore the statistics in Activity Monitor. You can use Instruments to check for leaks.

As an example of why the Activity Monitor should be ignored: if you make a 500 MiB allocation in 1 KiB chunks, and then free the odd-numbered chunks, obviously they can't be returned to the operating system because the page granularity is 4 KiB minimum on most modern systems. If you allocate the same 500 MiB in 1 MiB chunks and free the odd-numbered chunks, they'll be returned to the OS and memory usage will drop by 250 MiB as reported by Activity Monitor. (Note the 4 KiB threshold is NOT the threshold at which this behavior occurs. It depends on the exact allocation behavior by malloc(), and some parameters which, on OS X, depend on the CPU and amount of RAM.)

However, it's probably irrelevant. In each case, if you allocate the 250 MiB again, you'll be back where you started. It's nice to use less private memory, but this only affects how well your application plays with others.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • Thanks, but I'm not sure my 2009 macbook is even powerful enough to run Instruments. I've got it stuttering and sending the laptop fan into overdrive for about 10 minutes monitoring the opening of one window, which normally takes about 5 seconds with Instruments not running. – Christian J. B. Nov 23 '12 at 01:53
  • @ChristianJ.B.: Hm, that's interesting. My mac from 2005 can run it well enough... – Dietrich Epp Nov 23 '12 at 01:54
  • I'm running Instruments->leaks if that's any help. – Christian J. B. Nov 23 '12 at 01:56
  • @ChristianJ.B.: As a "poor-man's leak detector" you can open and close a few windows, measure memory usage, then open and close a lot more windows (but never have more windows open at the same time). If the memory usage keeps going up as you open and close windows, you have a leak. – Dietrich Epp Nov 23 '12 at 02:06
  • @ChristianJ.B.: If you can't run Instruments then I don't know what to say. Try asking a question about why the Instruments leak detector isn't working. I found no noticeable performance drop when using the leak detector on my bottom-of-the-line MacBook Air -- everything was as smooth as ever. – Dietrich Epp Nov 23 '12 at 02:23
  • I found this [stackoverflow page](http://stackoverflow.com/questions/6797728/xcode-4-1-instruments-hardly-working-for-me) about Instruments running slow. I'm going to try to run it separately and not call it from profile – Christian J. B. Nov 23 '12 at 02:26