// Option 2 NSImage *image = [[NSImage alloc] initWithContentsOfFile: inPath];
/* do some stuff */ [image release]; It seems very likely that the error is in the "do some stuff". I built an app from your code and sat it in a while loop, and it didn't leak. It had the same behavior as you report for the second version of your code. -Ken Cocoa Frameworks On Wed, Jun 2, 2010 at 6:51 AM, Ken Tozier <kentoz...@comcast.net> wrote: > Thanks all for the replies > > Re point #1: I was using Activity Monitor and both the "Real Memory" and > "Virtual Memory" columns showed this 100+ MB leak every 5-10 seconds. After > a minute or so of running, My app had gobbled up almost 2 gigs of memory. > > Re point #2: All the thumbnail conversion code is contained within this one > method, so once it enters the loop, it doesn't exit till it's done. > > I tried using [[NSGarbageCollector defaultCollector] collectExhaustively], > as Jonathan suggested, tried [image setCacheMode: NSImageCacheNever], but > neither of those slowed the ferocious gobbling of memory. > > I finally resorted to using CGxxx functions and the problem disappeared. My > App now hums along generating 12 to 15 thumbnails per second with a memory > footprint in the 20 to 30 MB range. Here's what worked: > > > - (NSString *) createJPEGThumbnail:(NSString *) inPath > site:(NSString *) inSite > { > NSDictionary *siteRecord, > *pubRecord; > > NSString *sourceName = > [inPath lastPathComponent], > *sourceRoot > = [sourceName stringByDeletingPathExtension], > *destName > = [[sourceRoot stringByAddingPercentEscapesUsingEncoding: > NSUTF8StringEncoding] stringByAppendingPathExtension: @"jpg"], > *pubCode > = [self pubCodeFromPath: inPath], > *thumbPath; > > NSFileManager *manager = > [NSFileManager defaultManager]; > > siteRecord = [thumbDirectories > objectForKey: inSite]; > > pubRecord = [[siteRecord objectForKey: > @"publications"] objectForKey: pubCode]; > > if (pubRecord == nil) > pubRecord = [[siteRecord objectForKey: > @"publications"] objectForKey: @"~MISCELLANEOUS"]; > > thumbPath = [[pubRecord objectForKey: > @"thumb_path"] stringByAppendingPathComponent: destName]; > > if (![manager fileExistsAtPath: thumbPath]) > { > NSURL *sourceURL > = [NSURL fileURLWithPath: inPath], > > *destURL = [NSURL fileURLWithPath: thumbPath]; > > NSString *imageType > = UtilPreferredUTIForFile(inPath); > NSNumber *maxPixels > = [NSNumber numberWithInt: maxDimension]; > NSDictionary *sourceOptions = > [NSDictionary dictionaryWithObjectsAndKeys: > > imageType, > kCGImageSourceTypeIdentifierHint, > > kCFBooleanFalse, > kCGImageSourceShouldCache, > > kCFBooleanTrue, > kCGImageSourceCreateThumbnailFromImageAlways, > > maxPixels, > kCGImageSourceThumbnailMaxPixelSize, > > nil]; > > > CGImageSourceRef imageSourceCG = > CGImageSourceCreateWithURL((CFURLRef) sourceURL, (CFDictionaryRef) > sourceOptions ); > if (imageSourceCG != NULL) > { > NSDictionary *imageProps > = (NSDictionary *) CGImageSourceCopyPropertiesAtIndex(imageSourceCG, 0, > NULL); > int w > = [[imageProps objectForKey: @"PixelWidth"] > intValue], > h > = [[imageProps objectForKey: @"PixelHeight"] > intValue]; > > NSRect thumbRect > = [self thumbRectWithSize: NSMakeSize(w, h)]; > > NSDictionary *destOptions > = [NSDictionary dictionaryWithObjectsAndKeys: > > [NSNumber numberWithInt: > thumbRect.size.width], kCGImagePropertyPixelWidth, > > [NSNumber numberWithInt: > thumbRect.size.height], kCGImagePropertyPixelHeight, > > nil]; > > CGImageRef imageRefCG > = CGImageSourceCreateThumbnailAtIndex(imageSourceCG, 0, > (CFDictionaryRef) sourceOptions); > if (imageRefCG != NULL) > { > CGImageDestinationRef destRef = > CGImageDestinationCreateWithURL((CFURLRef) destURL, kUTTypeJPEG, 1, NULL); > if (destRef != NULL) > { > CGImageDestinationAddImage(destRef, > imageRefCG, (CFDictionaryRef) destOptions); > CGImageDestinationFinalize(destRef); > CFRelease(destRef); > } > CFRelease(imageRefCG); > } > > CFRelease(imageSourceCG); > > } > } > > // make sure it worked > if ([manager fileExistsAtPath: thumbPath]) > return thumbPath; > else > return nil; > } > > > > On Jun 1, 2010, at 6:47 PM, Tony Romano wrote: > > Hi Ken, >> >> This code by itself should not be causing a leak. Couple of questions: >> >> 1. How do you know you have a memory leak? Sound like a silly question >> but you didn't tell us anything about what you are using to detect leaks. >> 2. Who is calling this code, how many times? If you are passing the >> image to something else in the sections you have commented out and you are >> calling this many times, your memory usage may grow senza any cache'ing that >> maybe happening. >> >> I would suggest putting a NSLog statement at the beginning and look at >> your output window to make sure the code is not called more than you think. >> >> -Tony Romano >> >> On May 31, 2010, at 6:41 PM, Ken Tozier wrote: >> >> Hi >>> >>> I'm trying to write a thumbnailer class that takes a path to a photo and >>> creates a thumbnail at a user specified size. The code creates the >>> thumbnails OK, but there's this monster memory leak, to the tune of about >>> 100 MB every 3-4 seconds, that seems to be related to NSImage. >>> >>> What's happening is that if I comment out the line that initializes a new >>> image, the memory leak disappears. I've tried forcibly releasing the images, >>> tried autoreleasing them, tried creating a fixed size buffer into which all >>> the images are read, nothing seems to work. >>> >>> I'm using garbage collection, so that along with the deliberate releasing >>> of the images, makes me wonder why the collector isn't getting the hint, >>> that it's ok to release the memory for these photos. Could someone point out >>> what I'm doing in the following code that prevents the images from getting >>> released? >>> >>> Thanks for any help >>> >>> - (NSString *) createJPEGThumbnail:(NSString *) inPath >>> site:(NSString *) inSite >>> { >>> NSDictionary *siteRecord, >>> *pubRecord; >>> >>> NSString *sourceName = >>> [inPath lastPathComponent], >>> *sourceRoot >>> = [sourceName stringByDeletingPathExtension], >>> *destName >>> = [[sourceRoot stringByAddingPercentEscapesUsingEncoding: >>> NSUTF8StringEncoding] stringByAppendingPathExtension: @"jpg"], >>> *pubCode >>> = [self pubCodeFromPath: inPath], >>> *thumbPath; >>> >>> NSFileManager *manager = >>> [NSFileManager defaultManager]; >>> >>> siteRecord = [thumbDirectories >>> objectForKey: inSite]; >>> pubRecord = [[siteRecord >>> objectForKey: @"publications"] objectForKey: pubCode]; >>> >>> if (pubRecord == nil) >>> pubRecord = [[siteRecord >>> objectForKey: @"publications"] objectForKey: @"~MISCELLANEOUS"]; >>> >>> thumbPath = [[pubRecord >>> objectForKey: @"thumb_path"] stringByAppendingPathComponent: destName]; >>> >>> if (![manager fileExistsAtPath: thumbPath]) >>> { >>> // I've tried both of these, didn't make the slightest >>> difference. >>> // Both leaked memory at a furious pace >>> >>> // Option 1: >>> NSImage *image >>> = [[[NSImage alloc] initWithContentsOfFile: inPath] >>> autorelease]; >>> >>> /* do some stuff */ >>> >>> >>> // Option 2 >>> NSImage *image >>> = [[NSImage alloc] initWithContentsOfFile: inPath]; >>> >>> /* do some stuff */ >>> >>> [image release]; >>> } >>> >>> // make sure it worked >>> if ([manager fileExistsAtPath: thumbPath]) >>> return thumbPath; >>> else >>> return nil; >>> } >>> _______________________________________________ >>> >>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >>> >>> 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: >>> http://lists.apple.com/mailman/options/cocoa-dev/tonyrom%40hotmail.com >>> >>> This email sent to tony...@hotmail.com >>> >>> >> -Tony >> >> > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > 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: > http://lists.apple.com/mailman/options/cocoa-dev/kenferry%40gmail.com > > This email sent to kenfe...@gmail.com > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com