I am fighting with an internal caching (about 90 MB for 15 mp image ) in CGContextDrawImage/CGDataProviderCopyData functions. 
Here is the stack-trace in profiler:
In all cases, IOSurface is created as a "cache", and isn't cleaned after @autoreleasepool is drained. 
 This leaves a very few chances for an app to survive. 
Caching doesn't depend on image size: I tried to render 512x512, as well as 4500x512 and 4500x2500 (full-size) image chunks. 
I use @autoreleasepool, CFGetRetainCount returns 1 for all CG-objects before cleaning them.   
The code which manipulates the data:
+ (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);
    }
}
 What I know about IOSurface: it's from the previously private framework IOSurface. 
 
CIContext has a function render: ... toIOSurface:. 
 
I've created my IOSurfaceRef and passed it to this function, and the internal implementation still creates its own surface, and doesn't clean it.  
So, do you know (or assume):  
1. Are there other ways to read CGImage's data buffer except 
 CGContextDrawImage/CGDataProviderCopyData ? 
2. Is there a way to disable caching at render? 
3. Why does the caching happen? 
4. Can I use some lower-level (while non-private) API to manually clean up system memory? 
Any suggestions are welcome.

                        
To answer your second question,
Is there a way to disable caching at render?setting the environment variable
CI_SURFACE_CACHE_CAPACITYto 0 will more-or-less disable theCIContextsurface cache. Moreover, you can specify a custom (approximate) cache limit by setting that variable to a given value in bytes. For example, settingCI_SURFACE_CACHE_CAPACITYto 2147483648 specifies a 2 GiB surface cache limit.Note it appears that all of a process's
CIContextinstances share a single surface cache. It does not appear to be possible to use separate caches perCIContext.