• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Leaking Memory
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Leaking Memory


  • Subject: Re: Leaking Memory
  • From: mmalcolm crawford <email@hidden>
  • Date: Fri, 24 Jan 2003 21:36:52 -0800

On Friday, January 24, 2003, at 06:07 PM, Robert Goldsmith wrote:

Objects are "cleared" (deallocated) when their retain count drops to 0.

I am well aware of this so maybe my question should be 'when do retain
counts of autoreleased objects reach zero'. Now, as you have rightly
pointed out, in the absence of any other retains on the object, this is
when the autorelease pool is released.

OK...


"Generally", that's as much as we need to, or -- in the absence of any
other context -- can, say (bearing in mind basic rules of memory
management).

As a C programmer at heart, this is not good enough (just as the simple
memory -allocation- management was not good enough for you).

My understanding was that the context was primarily "newbies".
For a newcomer to Cocoa, the most important things to understand initially are the basic rules, and worry about optimisation later. Nevertheless, as you exemplify, many newcomers to Cocoa (although perhaps sadly not enough...) are concerned about memory efficiency -- hence my "total" example.

I would like to know exactly how long objects could stay around - give me error bars, if you will.

This is covered in the documentation: assuming an object is autoreleased, and in the absence of any other retains on the object, until the end of the current event loop.


You see, this is just as important as the retain/release cycle because,
although it will not cause a bus error, it can cripple a program - and
because it does not cause an error, many programmers may be blissfully
unaware they have 2000 temporary objects eating up memory and forcing
os x to use virtual memory pages.

That was precisely the point of my "total" example.


The Application Kit creates a pool at the beginning of the event loop
and releases it at the end.

Ok, so in an event driven application, life is easier because you can
create thousands of objects and they will be cleared at the start of
the next event loop (how often is that, btw? any ideas?).

An event is typically a mouse event or press. An autorelease pool is created just before your application deals with an event, and freed after the event has been handled. Typically you can think of this as a pool being created just before your action method is called, and released after it finishes.


How about NON-event based applications?

In non-event-based applications you are responsible for creating your own autorelease pools.

For instance, if I was to have a method that used 5 temporary objects
(created with convenience messages to the class). This method is
messaged 1 million times. I was a good programmer and set up a pool
when I started. Are the temporary objects released like an int would be
in a c function? Or are they placed in the autorelease pool? I assume
the latter.

Correct -- as per my previous reply, autoreleasepools can be nested, and autoreleased objects are added to the most recently created pool.

So how often should a pool be cleared; i.e. how quickly does the system get bogged down vs how long does it take to release the pool and create another?

How quickly the system gets bogged down will, as with any program, depend on how much memory the objects you create themselves occupy, how many you create, and the available system RAM.

Determination of how many pools to create and where is likely to be the result of profiling, or perhaps judicious anticipation in the case of long loops.

And can you release a pool and create a new one (without a pool below
to catch objects) without errors or leaks?

Yes:

NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
// string added to myPool
NSString *myString = [NSString stringWithFormat:@"%@ %@", firstname, lastName];
NSLog(myString);
[myPool release];

although it is also possible to introduce errors:

NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
// string added to myPool
NSString *myString = [NSString stringWithFormat:@"%@ %@", firstname, lastName];
// string released by myPool
[myPool release];
// crash
NSLog(myString);


And, back to AppKit, if you create your own pool, is it this pool that
gets released at the end of each event loop? I assume not

Correct assumption.


does that mean that, if you are not careful, your pool ends up filled with AppKit temporary items?

If you did not release your own autorelease pools, then yes. However the whole point is that you create pools of your own, *then release them.


Perhaps this is a case where the simplicity of what's going on is not actually apparent.

You can perhaps think of an autoreleasepool as a special mutable array (again see "Cases that cause confusion" in:
<http://www.stepwise.com/Articles/Technical/2001-03-11.01.html>
)
When you autorelease an object, it is added to the current autorelease pool, just as you might with
[myMutableArray addObject:myObject];
The difference being that it (the object) is not retained.

When the pool is itself released, it sends a release message to all the objects that were added (remembering that an object may appear in more than once, and so receive more than one release message), just as would be the case in the array.

So creating your own pools as you would in non-event driven apps is a very bad idea for AppKit apps.

On the contrary, again as the "total" example in my previous message illustrated, and your initial thrust suggested, judicious creation of your own pools may serve to reduce the peak memory footprint of an application, with considerable benefit.

I also suspect that, with so much talk of autorelease pools, many
newbies think that once they have that down pat, they don't need to
think about memory management further... a very incomplete and
inaccurate view indeed (if you want to be an efficient programmer, that
is).

I would not necessarily say "inaccurate", but I would probably agree with "incomplete". This is where your C heritage may stand you in better stead than those whose primary experience has been with, say, Java, where memory considerations are typically not as high priority ("the garbage collector just takes care of it"). Note: This is not a denigration of Java, or Java developers in general. This is an observation based on a reasonably large sample.

mmalc
Beginning to think this should be written up as an article...
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

References: 
 >Re: Leaking Memory (From: Robert Goldsmith <email@hidden>)

  • Prev by Date: Creating a screen saver
  • Next by Date: nstablecolumns in nstableviews in an nssplitview
  • Previous by thread: Re: Leaking Memory
  • Next by thread: Re: Leaking Memory
  • Index(es):
    • Date
    • Thread