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: William Squires <email@hidden>
- Date: Sun, 30 Nov 2008 18:44:54 -0600
On Nov 4, 2008, at 1:21 PM, Bill Bumgarner wrote:
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.
Wouldn't this make your locals go >poof!<??
b.bum
_______________________________________________
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:
40satx.rr.com
This email sent to email@hidden
_______________________________________________
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