2010-10-27 6 views
1

Essayer de trouver la fuite dans mon code j'ai enlevé toute la chose qui n'a pas d'importance, en laissant le code suivant:Fuite dans CGBitmapContextCreate

static int last_memory = 0; 

void report_memory(NSString *name) { 
    struct task_basic_info info; 
    mach_msg_type_number_t size = sizeof(info); 
    kern_return_t kerr = task_info(mach_task_self(), 
            TASK_BASIC_INFO, 
            (task_info_t)&info, 
            &size); 
    if(kerr == KERN_SUCCESS) { 
     int change = (int)info.resident_size - last_memory; 
     NSLog(@"%@ >>> Memory in use: %u (change: %d Kb)", name, info.resident_size, change/1024); 
     last_memory = info.resident_size; 
    } else { 
     NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); 
    } 
} 

- (CGContextRef) createBitmapContextOfSize:(CGSize) size { 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    bitmapBytesPerRow = (size.width * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * size.height); 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    bitmapData = malloc(bitmapByteCount); 
    if (bitmapData == NULL) { 
     NSLog(@"Memory not allocated!"); 
     CGColorSpaceRelease(colorSpace); 
     return NULL; 
    } 
    context = CGBitmapContextCreate (bitmapData, 
            size.width, 
            size.height, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedLast); 
    CGContextSetAllowsAntialiasing (context,NO); 
    if (context== NULL) { 
     free (bitmapData); 
     CGColorSpaceRelease(colorSpace); 
     NSLog (@"Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace); 
    return context; 
} 

- (IBAction) clickButton:(UIButton *)sender { 
    report_memory(@"begin"); 
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test"]; 
    UIImage *image = [UIImage imageWithContentsOfFile:path]; 

    report_memory(@"image_created"); 

    CGContextRef myBitmapContext = [self createBitmapContextOfSize:CGSizeMake(256, 256)]; 
    if (!myBitmapContext){ 
     return; 
    } 
    report_memory(@"bitmap_context_created"); 
    CGContextDrawImage(myBitmapContext, CGRectMake(0, 0, 256, 256), image.CGImage); 
    report_memory(@"draw_image"); 
    CGImageRef ref = CGBitmapContextCreateImage(myBitmapContext); 
    report_memory(@"image_context_created"); 
    CGContextRelease(myBitmapContext); 
    report_memory(@"bitmap_context_released"); 
    UIImage *result = [UIImage imageWithCGImage:ref]; 
    report_memory(@"image_created"); 
    CGImageRelease(ref); 
    report_memory(@"image_context_released"); 
    imageView.image = result; 
    report_memory(@"image_assigned"); 
} 

(« test » est 256x256 image JPEG). La console a montré ce qui suit après quelques clics:

begin >>> Memory in use: 18866176 (change: -12 Kb) 
image_created >>> Memory in use: 18870272 (change: 4 Kb) 
bitmap_context_created >>> Memory in use: 18870272 (change: 0 Kb) 
draw_image >>> Memory in use: 19140608 (change: 264 Kb) 
image_context_created >>> Memory in use: 19140608 (change: 0 Kb) 
bitmap_context_released >>> Memory in use: 19140608 (change: 0 Kb) 
image_created >>> Memory in use: 19140608 (change: 0 Kb) 
image_context_released >>> Memory in use: 19140608 (change: 0 Kb) 
image_assigned >>> Memory in use: 19140608 (change: 0 Kb) 

Une perte nette de 256Kb par clic (égal à 256x256x4). La même tendance pourrait être observée dans l'outil de performance des allocations. Tout ce qui pointe vers le CGBitmapContext n'est pas publié. Je ne vois pas ce que je fais de mal ...

Répondre

2

Laissez le CGBitmapContextCreate allouer la mémoire elle-même en fournissant NULL comme premier argument (bitmapData). Cela vous libère de la gestion de votre allocation de mémoire - que vous ne libérez pas pour le moment.

+0

Merci beaucoup. Copié la fonction depuis internet ... –