Я работаю над программой MacOS в Objective C, которая должна создавать миниатюры в памяти для отправки на сервер. Для выполнения этой операции используется следующий код. По мере запуска программы каждый раз, когда вызывается этот метод, возникает утечка около 40 МБ. Я подозреваю, что у меня нет чего-то действительно основного, но я не вижу источника проблемы.Создание эскизов вызывает утечку (MacOS, Obj C)
Я должен добавить, что я также попытался создать один контекст для использования в течение всей жизни программы, и проблема, если что-нибудь, кажется несколько хуже.
Когда я запускаю Инструменты, распределения для категории «VM: ImageIO_JPEG_Data» растут по одному распределению 40 МБ каждый раз при его вызове. Ответственной библиотекой является «ImageIO», а ответственным абонентом является «ImageIO_Malloc».
- (void) createPhotoThumbnail
{
NSURL* fileURL = [NSURL fileURLWithPath : _imagePath];
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, MAX_THUMB_DIM, MAX_THUMB_DIM, 8, 0,
colorspace, (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CIContext *ciContext = [CIContext contextWithCGContext: bitmapContext options: @{}];
if (fileURL)
{
CIImage *image = [[CIImage alloc] initWithContentsOfURL: fileURL];
if (image)
{
// scale the image
CIFilter *scaleFilter = [CIFilter filterWithName: @"CILanczosScaleTransform"];
[scaleFilter setValue: image forKey: @"inputImage"];
NSNumber *scaleFactor = [[NSNumber alloc] initWithFloat: ((float) MAX_THUMB_DIM)/
((float)MAX(_processedWidth, _processedHeight))];
[scaleFilter setValue: scaleFactor forKey: @"inputScale"];
[scaleFilter setValue: @1.0 forKey: @"inputAspectRatio"];
CIImage *scaledImage = [scaleFilter valueForKey: @"outputImage"];
NSMutableData* thumbJpegData = [[NSMutableData alloc] init];
CGImageDestinationRef dest = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)thumbJpegData,
(__bridge CFStringRef)@"public.jpeg",
1,
NULL);
if (dest)
{
CGImageRef img = [ciContext createCGImage:scaledImage
fromRect:[scaledImage extent]];
CGImageDestinationAddImage(dest, img, nil);
if (CGImageDestinationFinalize(dest))
{
// encode it as a string for later
_thumbnail = [thumbJpegData base64EncodedStringWithOptions: 0];
}
else
{
DDLogError(@"Failed to generate photo thumbnail");
}
CGImageRelease(img);
CFRelease(dest);
}
else
{
DDLogError(@"Failed to finalize photo thumbnail image");
}
thumbJpegData = nil;
}
}
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorspace);
ciContext = nil;
}
UPDATE: Я включил код использовать CGAffineTransform вместо фильтра с «CILanczosScaleTransform» и этот симптом не изменился. Затем я использовал совершенно новый метод (фрагмент ниже), но проблема остается.
NSImage *thumbnail = [[NSImage alloc] initWithSize: newSize];
[thumbnail lockFocus];
[sourceImage setSize: newSize];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[sourceImage compositeToPoint: NSZeroPoint operation: NSCompositeCopy];
[thumbnail unlockFocus];
NSData *tiff = [thumbnail TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData: tiff];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
NSData *thumbJpegData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
Это заставляет меня думать, что проблема, возможно, связана с чем-то присущим образом я делаю это. Мне трудно поверить, что два разных метода масштабирования изображений будут демонстрировать такую же утечку.
Насколько велики ваши входные изображения, которые вы масштабируете? Вы используете ARC? – Sven
@Sven - Несмотря на самоограничивающиеся замечания OP, это не обычное «простое несоблюдение« Create Rule », и это не вопрос ARC. Я могу воспроизвести поведение, описанное OP, используя ARC, и я не вижу здесь ничего явно неправильного. Для меня это утечка несжатого размера изображения (поэтому мой снимок экрана 2888x1800 пропускает 20 мб для каждого изображения). Использование иваров здесь немного неряшливо, но даже после того, как один из них исправит, фундаментальная проблема утечки памяти выглядит законной для меня. – Rob
Да, используя ARC. Мои изображения - это разные фотографии, поэтому размер варьируется довольно немного (от более старой 3-мегапиксельной камеры до более новой 12-мегапиксельной камеры), но размер кажется согласованным на уровне около 40 МБ на изображение. –