Re: Leaking Memory
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.