Objective c 应用程序使用的内存增长非常快

Objective c 应用程序使用的内存增长非常快,objective-c,macos,Objective C,Macos,写了一个简单的程序来填满我驱动器上的所有空间。它有一个非常简单的逻辑: 10创建一个文件 20写入N(我的情况下为40)大小为M的随机块(我的情况下为100 MiB) 30关闭文件 40转到10 好的,我刚刚从头开始创建了一个新的Cocoa项目,并将代码放在ApplicationIDFinishLaunching中。给你 -(无效)应用程序设计完成启动:(NSNotification*)通知 { fm=[NSFileManager新]; 无符号长尺寸=0; 无符号long-long-size

写了一个简单的程序来填满我驱动器上的所有空间。它有一个非常简单的逻辑:

  • 10创建一个文件
  • 20写入N(我的情况下为40)大小为M的随机块(我的情况下为100 MiB)
  • 30关闭文件
  • 40转到10
好的,我刚刚从头开始创建了一个新的Cocoa项目,并将代码放在
ApplicationIDFinishLaunching
中。给你

-(无效)应用程序设计完成启动:(NSNotification*)通知
{
fm=[NSFileManager新];
无符号长尺寸=0;
无符号long-long-sizeMax=0;
NSString*路径;
NSData*数据;
NSFileHandle*myHandle;
用于(长i=0;;++i){
如果(i%40L==0){//N=40
sizeMax=[self-currentMaxSize];
尺寸=0;
path=[NSString stringWithFormat:@/Users/user/Desktop/loltest/lol_u%f.txt],[NSDate timeIntervalSinceReferenceDate];
[fm createFileAtPath:路径内容:[NSData data]属性:无];
[myHandle closeFile];
myHandle=[NSFileHandle fileHandleForWritingAtPath:path];
}
[myHandle seekToEndOfFile];
数据=[自随机数据];
大小+=数据长度;
[myHandle writeData:数据];
数据=零;
如果(大小>=sizeMax){
[myHandle closeFile];
打破
}
}
NSLog(@“好”);
}
-(无符号长)currentMaxSize
{
返回[[fm AttributesOfficeSystemForPath:@”/“错误:nil][NSFileSystemFreeSize]unsignedLongValue];
}
-(NSData*)随机数据
{
常量int LENGTH=100*1024*1024;//M
char*bytes=(char*)malloc(LENGTH*sizeof(char));//好吧,这应该是静态的并且被调度过一次,但是我在尝试修复泄漏时删除了它
对于(NSInteger i=0;i
当我运行那个程序时,1分钟后,1个GiB泄漏并静止。在系统的内存管理窗口和活动监视器上结束,显示使用了60 GiB的交换

我运行的仪器告诉我,
总字节数
部分等于活动监视器为应用程序显示的内容。然而,一次只有一个对象,分配图是一个saw,随机数据的指针在函数调用之间是常量。也许
NSData
以某种方式保存了源数组,但我根本无法解决这个难题


您可能希望在该循环的内容周围有一个@autoreleasepool{},否则它创建的临时对象将无法清理。这可能是问题的根源。

您可能希望在该循环的内容周围有一个@autoreleasepool{},否则它创建的临时对象将无法清理。这可能是您的问题的根源。

您需要担心的不是“总字节数”(因为这包括已释放的内存)。您应该担心的是“活动字节数”(看起来不错)。您需要担心的不是“总字节数”(因为这包括已释放的内存)。而是“活动字节数”你应该担心的(这看起来很好)。很有趣,从来没有这样想过。它很有效,非常感谢!但我有一个问题:为什么我要把整个函数内容放在
@autoreleasepool
(或者甚至像UIKit样板文件一样放在
main()
中)它不起作用?为什么这不是由嵌套块继承的?从那以后,将
@autorelease
放在
main()
中有什么意义呢?(文档中说
在哪里使用,而不是
为什么
)@autoreleasepool在结束时释放其池中的对象。}池是继承的,但您仍然在其中。有趣的是,从来没有这样想过。它成功了,非常感谢!但我有一个问题:为什么我要将整个函数内容放在
@autoreleasepool
(或者甚至像UIKit样板一样将
main()
的内容放在其中)它不会工作?为什么这不是由嵌套块继承的?从那以后,将
@autorelease
放在
main()
?(文档说
在哪里使用,而不是
为什么
)@autoreleasepool在关闭时释放其池中的对象。)池是继承的,但您仍然在其中。