我正在使用CGContextDrawImage
/CGDataProviderCopyData
函数中的内部缓存(对于15 mp图像,大约90 MB)。
这是探查器中的堆栈跟踪:
在所有情况下,IOSurface
都会创建为“缓存”,并且在@autoreleasepool
耗尽后不会清除。这为应用程序留下了很少的生存机会。
缓存不取决于图像大小:我尝试渲染512x512
以及4500x512
和4500x2500
(全尺寸)图像块。
我使用@autoreleasepool
,CFGetRetainCount
在清除所有1
-objects之前返回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
的了解:它来自以前的私有(private)框架IOSurface
。CIContext
具有函数render: ... toIOSurface:
。我已经创建了
IOSurfaceRef
并将其传递给此函数,并且内部实现仍会创建其自己的表面,并且不会对其进行清理。因此,您知道(或假设):
1.除了CGImage的数据缓冲区外,还有其他方法可以读取
CGContextDrawImage
/CGDataProviderCopyData
吗?2.有没有一种方法可以禁用渲染时的缓存?
3.为什么会发生缓存?
4.我可以使用一些较低级别的(非私有(private)的)API来手动清理系统内存吗?
欢迎任何建议。
最佳答案
为了回答您的第二个问题,Is there a way to disable caching at render?
将环境变量CI_SURFACE_CACHE_CAPACITY
设置为0将或多或少禁用CIContext
表面缓存。此外,您可以通过将变量设置为给定的字节数来指定自定义(近似)缓存限制。例如,将CI_SURFACE_CACHE_CAPACITY
设置为2147483648会指定2 GiB表面缓存限制。
注意,似乎所有进程的CIContext
实例共享一个表面缓存。每个CIContext
似乎无法使用单独的缓存。