Re: Forcing garbage collection, freeing up memory, thrashing
Re: Forcing garbage collection, freeing up memory, thrashing
- Subject: Re: Forcing garbage collection, freeing up memory, thrashing
- From: Bill Bumgarner <email@hidden>
- Date: Tue, 04 Nov 2008 11:21:00 -0800
On Nov 4, 2008, at 10:46 AM, Sean McBride wrote:
Hi all,
I have a 64 bit, Cocoa, GC app. It loads many large bitmap files.
Each
is about 500 MiB, and the user may want to load about 50 of them.
When
each file is opened, I read the entire file, then downscale the
image to
a smaller resolution. I then no longer need the large image.
Basically my code is like:
- (void)openFiles:(NSArray*)filePaths
{
for each path in filePaths
load large image
downsample
force collection
}
I call:
objc_collect (OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE);
to force the collection. I've breaked in finalize, and forcing the
collection does work.
However, Activity Monitor still shows my 'Real Memory' growing very
large. It doesn't fall back until (I think) the next run through the
run loop.
When physical memory is exhausted, the machine thrashes badly. If I
change my implementation to load only 1 file, then let the runloop
continue, then load the next file, etc. I never even exhaust my
physical
memory.
Why is that?
(Yes, I know it would be better to not block the main thread with
such a
long task, but this app is for in-house, so it's ok.)
Have you used the Object Graph instrument in Instruments and/or gdb's
info gc-references/gc-roots to determine what is sticking around and
why? Analysis with said tools can tell you exactly what is going on.
In this case, though, I have an idea what is happening. I bet your
image objects are being falsely rooted -- being kept alive -- by the
stack. The collector must scan the entire stack for pointers,
including a bit of slop beyond the "bottom" of the stack (because the
bottom may not be the bottom). That is, GCC's convention is that the
stack layout is opaque.
Thus, it is possible for objects to live for longer than they should
if there is a pointer (or something that looks like a pointer) on the
stack somewhere... anywhere... that refers to the object.
Easy fix; clear the stack at the top or bottom of your loop. Clear
it from one function above any that stick references on the stack.
I.e. make your loop a simple wrapper around a function where the loop
clears the stack at the top or bottom.
The collector provides API for this:
objc_clear_stack(OBJC_CLEAR_RESIDENT_STACK);
NSRunLoop does this automatically as it passes through each loop.
Since you are blocking the run loop, you'll have to do this for it.
b.bum
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden