gpt4 book ai didi

macos - NSView缓存显示矩形:toBitmapImageRep: Memory Leak

转载 作者:行者123 更新时间:2023-12-03 17:09:49 25 4
gpt4 key购买 nike

在我的项目(Cocoa)中,我需要比较两个 NSView 的视觉相似度。这是比较函数:

- (void)compareWithHandler: (void (^)(CGFloat fitness)) handler {
@autoreleasepool {
__block CGFloat fitness = 0;
__block NSInteger count = 0;

NSBitmapImageRep *bitmap1 = [_lennaImgView bitmapImageRepForCachingDisplayInRect:[_lennaImgView bounds]];
NSBitmapImageRep *bitmap2 = [backgroundView bitmapImageRepForCachingDisplayInRect:[backgroundView bounds]];

[_lennaImgView cacheDisplayInRect:_lennaImgView.bounds toBitmapImageRep:bitmap1];
[backgroundView cacheDisplayInRect:backgroundView.bounds toBitmapImageRep:bitmap2];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSInteger w = [bitmap1 pixelsWide];
NSInteger h = [bitmap1 pixelsHigh];
NSInteger rowBytes = [bitmap1 bytesPerRow];
unsigned char* pixels1 = [bitmap1 bitmapData];
unsigned char* pixels2 = [bitmap2 bitmapData];

int row, col;
for (row = 0; row < h; row++){
@autoreleasepool {
unsigned char* rowStart1 = (unsigned char*)(pixels1 + (row * rowBytes));
unsigned char* rowStart2 = (unsigned char*)(pixels2 + (row * rowBytes));
unsigned char* nextChannel1 = rowStart1;
unsigned char* nextChannel2 = rowStart2;
for (col = 0; col < w; col++){
unsigned char r1, g1, b1, a1, r2, g2, b2, a2;

r1 = *nextChannel1;
nextChannel1++;
g1 = *nextChannel1;
nextChannel1++;
b1 = *nextChannel1;
nextChannel1++;
a1 = *nextChannel1;
nextChannel1++;
r2 = *nextChannel2;
nextChannel2++;
g2 = *nextChannel2;
nextChannel2++;
b2 = *nextChannel2;
nextChannel2++;
a2 = *nextChannel2;
nextChannel2++;

unsigned char ary[] = {r1, r2, g1, g2, b1, b2};
double dist = vectorDistance(ary);
fitness += (CGFloat)map(dist, 0, 442, 1, 0);
count ++;
}
}
}
fitness /= count;

dispatch_async(dispatch_get_main_queue(), ^{
handler(fitness);
});
});
}
}

当我运行它时,我注意到巨大的内存泄漏,可能超过 2GB。在Xcode Instruments中我发现这两行占用了大部分内存:

    NSBitmapImageRep *bitmap1 = [_lennaImgView bitmapImageRepForCachingDisplayInRect:[_lennaImgView bounds]];
NSBitmapImageRep *bitmap2 = [backgroundView bitmapImageRepForCachingDisplayInRect:[backgroundView bounds]];

仪器中的屏幕截图: enter image description here

我读过一些类似的问题,但似乎没有一个有帮助。

<小时/>

更新

Rob 建议我可能过于频繁地调用此函数。是的,我反复调用它,但我认为我不会在最后一次调用完成之前调用它。

这是我如何使用该功能:

- (void)draw {      
// Here I make some changes to the two NSView
// Blablabla

// Call the function
[self compareWithHandler:^(CGFloat fitness) {
// Use the fitness value to determine how we are going to change the two views

[self draw];
}];
}

我没有在僵尸模式下运行它

最佳答案

我能体现此问题的唯一方法是重复调用此例程,而不等待先前的调用完成。在那种情况下,我有一个相当激进的增长曲线:

enter image description here

但是,如果我给它一点喘息的空间(即,我不是不停地循环,而是让例程 dispatch_async 在完成后对其自身进行调用,每个路标都指示对例程的单独调用) ,很好:

enter image description here

因此,要么您过于频繁地调用此例程,并且没有给操作系统清理这些缓存的机会,要么您可能打开了僵尸或其他一些内存调试选项。但内存问题似乎并不是来自这段代码本身。

如果您没有不间断地调用此函数,也没有打开任何内存调试选项,我可能建议使用“调试内存图”(请参阅​​ https://stackoverflow.com/a/30993476/1271826 )功能来识别任何强引用循环。另外,虽然这里看起来不太可能,但有时您会看到由于某些父对象正在泄漏而出现泄漏(因此请查找可能未释放的各种父类的实例,而不是关注正在泄漏的大项)。

关于macos - NSView缓存显示矩形:toBitmapImageRep: Memory Leak,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41402675/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com