• 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
Excessive NSImage caching (or leaking)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Excessive NSImage caching (or leaking)


  • Subject: Excessive NSImage caching (or leaking)
  • From: David Remahl <email@hidden>
  • Date: Wed, 23 Apr 2003 21:10:14 +0200

Dear list,

I have a problem with some code dealing with NSWorkspace / NSImage leaking loads and loads (well, relatively speaking, anyway) of memory. The code that leaks uses -[NSWorkspace iconForFile:(NSString*)file] to retrieve the icon of a file at a certain place.

The code runs in a separate thread, rigged with three autorelease pools that empty at certain levels.

Since I'm only interested in the biggest of the icon sizes present, I extract the correct NSBitmapImageRep from the image. In essence, this is the code I'm using:

- (void)thread
{
while( !quit )
{
NSAutoreleasePool *autoPool = [[NSAutoreleasePool alloc] init];

somePath = [self getAPath]; /* some path indicates a different file for each pass through the loop. */
NSBitmapImageRep *largestRep = [self getIconRepForFileAtPath:somePath];

unsigned char *bmpData = [lagestRep bitmapData];
// do whatever to bmpData;

[autoPool release];
}
}

- (NSBitmapImageRep *)getIconRepForFileAtPath:(NSString *)path
{
NSImage *icon= [[NSWorkspace sharedWorkspace] iconForFile:path];
NSArray *reps = [icon representations];
NSBitmapImageRep *rep = nil;

if( [reps count] )
rep = [reps objectAtIndex:0];
return rep;
}

Profiling and memory debugging using OmniObjectMeter (and ObjectAlloc) reveal a lot of interesting things about this code.

One curious thing about the code is that while [[NSWorkspace sharedWorkspace] iconForFile:path] executes in almost no time, the thing that takes a lot of time is the [icon representations] message. According to the profiling, most of the execution time is then spent to actually read the icon data - ie, it is loaded lazily when needed.

My first question: Is there a way to avoid the lazy loading of _all_ the representations, when the only one I'm really interested in is representation at index 0? There is no public NSImage way to get at just a single representation, and the private interfaces are way too contrived for me to even think of using them.

My other question concerns the actual memory leak. It turns out, that for each loop in -thread, quite a few objects leak, even though everyone can see that I have properly balanced everything. The following objects leak more or less once per representation per loop:

NSView
NSWindowGraphicsContext
CFArray (multiple variable)
CFArray (store-deque)
Anonymous bytes (probably cached data related to the above classes)

Note that no NSImages leak, nor do any NSBitmapImageReps.

Analyzing the retain count history of the objects above (in OOM), I find that they are one release short. They all came into existence in [NSImage representations] and were all retained / released / autoreleased a number of times.

I'm not sure wether this is a real bug, or if its just some aggressive caching policy gone terribly wrong. Or if it perhaps is a side-effect of me using it from a secondary thread.

But the end result is a massive leakage. It is a difficult bug to work around, since I don't have any references to the objects that leak. It should be noted that the problem seems to be in how icns images are handled. If I replace the NSWorkspace call with something like this:

NSImage *icon = [[[NSImage alloc] initWithContentsOfFile:@"/path/to/someIcon.icns"] autorelease];

the net result is the same.

I request suggestions as to how to solve this...Please don't suggest I use the IconFamily class, since it uses initWithData: on the icns data to implement its -imageWithAllReps method.

The only solution I can see, is to reimplement all of NSWorkspace/NSImage's code to go from an IconRef to an icon image. That is what is being done in [icon representations] by means of various PlotIconRefTo* function calls (more or less private).

/ Sincerely, David Remahl
_______________________________________________
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.

  • Follow-Ups:
    • Re: Excessive NSImage caching (or leaking)
      • From: David Remahl <email@hidden>
  • Prev by Date: RE: NSData array?
  • Next by Date: Re: Get RTF from web and show in NSTextView
  • Previous by thread: PMU problems
  • Next by thread: Re: Excessive NSImage caching (or leaking)
  • Index(es):
    • Date
    • Thread