我正在嘗試撰寫一個命令列程式來從大量任意影像中提取縮略圖,但我遇到了 NSImage 中看起來像是基本記憶體泄漏的問題。
即使洗掉了所有其他有用的代碼,重復打開和關閉影像也會占用越來越多的記憶體。根據活動監視器,幾分鐘后(大約 40,000 次迭代)記憶體使用量達到 100 GB 或更多,然后顯示“您的系統已用完應用程式記憶體”或行程終止。這是在運行 Monterey 12.6 的具有 32GB RAM 的 M1 Mac 上。
我的測驗代碼如下。除了使用 CFRelease,我還嘗試使用自動釋放池并呼叫 [image release]。我還應該做些什么來阻止它耗盡記憶體?
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];
}
}
uj5u.com熱心網友回復:
[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://www.uj5u.com/yidong/515524.html
