我正试图编写一个命令行程序,从大量任意图像中提取缩略图,但在NSImage中却碰到了一个看起来很基本的内存泄漏。
即使所有其他做任何有用的事情的代码都被去掉了,重复打开和关闭一个图像也会消耗越来越多的内存。根据Activity的说法,几分钟后(以及大约40,000次迭代),内存使用量达到100 GB或更多,然后显示“您的系统已经耗尽了应用程序内存”,或者进程就会死掉。这是在运行蒙特利12.6的32 is内存的M1 Mac上。
我的测试代码如下。除了使用CFRelease之外,我还尝试使用自动释放池和调用映像发布。还有什么我应该做的来阻止它耗尽记忆吗?
char* path = "~/Desktop/IMG_9999.JPG";
for (int i=0; i<1000000; ++i)
{
NSString* str = [NSString stringWithUTF8String:path];
NSImage *image = [[NSImage alloc]initWithContentsOfFile:str];
NSSize size = [image size];
CFRelease(image); // also tried [image release] and @autorease { ... }
CFRelease(str);
}
下面是一个使用自动释放的小型自给测试。使用"/usr/bin/g++ -o test -stdlib=libc++ -framework AppKit test.mm“编译,并使用"./test /path/to/image.jpg”(或.heic或.png等)运行。
#import <AppKit/AppKit.h>
int main(int argc, const char** argv)
{
const char* path = argv[1];
for (int i=0; i<1000000; ++i)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSString* str = [NSString stringWithUTF8String:path];
NSImage* image = [[NSImage alloc]initWithContentsOfFile:str];
NSSize size = [image size];
if (i==0)
printf("size is %f x %f\n", size.width, size.height);
else if (i%1000==0)
printf("repeat %d\n", i);
[pool release];
}
}
发布于 2022-10-16 19:23:37
[NSString stringWithUTF8String:path]
返回一个自动释放的对象,但[[NSImage alloc]initWithContentsOfFile:str]
不返回。您需要一个自动释放池和[image release]
。
int main(int argc, const char** argv)
{
char* path = "/Volumes/Macintosh HD/Users/willeke/Desktop/Test image.png";
for (int i=0; i<10000; ++i)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSString* str = [NSString stringWithUTF8String:path];
NSImage* image = [[NSImage alloc] initWithContentsOfFile:str];
NSSize size = [image size];
if (i==0)
printf("size is %f x %f\n", size.width, size.height);
else if (i%1000==0)
printf("repeat %d\n", i);
[image release];
[pool release];
}
}
https://stackoverflow.com/questions/74069328
复制相似问题