Я борюсь с внутренним кэшированием (около 90 МБ для 15-мегапиксельного изображения) в CGContextDrawImage
/ CGDataProviderCopyData
функциях.
Вот трассировка стека в профилировщике:
![enter image description here](https://i.stack.imgur.com/g4BFH.png)
Во всех случаях IOSurface
создается как «кэш» и не являетсяне очищается после слива @autoreleasepool
.
Это оставляет очень мало шансов для приложения выжить.
Кэширование не зависит от размера изображения: я пытался рендерить 512x512
, а также 4500x512
и 4500x2500
(полноразмерные) фрагменты изображения.
Я использую @autoreleasepool
, CFGetRetainCount
возвращает 1
для всех CG
-объектов перед их очисткой.
Код, который манипулирует данными:
+ (void)render11:(CIImage*)ciImage fromRect:(CGRect)roi toBitmap:(unsigned char*)bitmap {
@autoreleasepool
{
int w = CGRectGetWidth(roi), h = CGRectGetHeight(roi);
CIContext* ciContext = [CIContext contextWithOptions:nil];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgContext = CGBitmapContextCreate(bitmap, w, h,
8, w*4, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef cgImage = [ciContext createCGImage:ciImage
fromRect:roi
format:kCIFormatRGBA8
colorSpace:colorSpace
deferred:YES];
CGContextDrawImage(cgContext, CGRectMake(0, 0, w, h), cgImage);
assert( CFGetRetainCount(cgImage) == 1 );
CGColorSpaceRelease(colorSpace);
CGContextRelease(cgContext);
CGImageRelease(cgImage);
}
}
Что я знаю о IOSurface
: это из ранее закрытого фреймворка IOSurface
.
CIContext
имеет функцию render: ... toIOSurface:
.
Я создал свой IOSurfaceRef
и передал его этой функции, а внутренняя реализация все еще создает свою собственную поверхность и не очищает ее.
Итак, знаете ли вы (или предполагаете):
1. Существуют ли другие способы чтения буфера данных CGImage, кроме CGContextDrawImage
/ CGDataProviderCopyData
?
2. Есть ли способ отключить кеширование при рендере?
3. Почему происходит кэширование?
4. Могу ли я использовать какой-нибудь низкоуровневый (хотя и не приватный) API для очистки системной памяти вручную?
Любые предложения приветствуются.