1

私は、常に実行され、キューに入れられたすべてを処理する OS X アプリに取り組んでいます。これらのジョブは、プロセスを stdout に記録します。バックグラウンドスレッドで実行されるwhileループを使用して、この情報をstdoutリアルタイムから取得しようとしています。問題は、12 時間実行した後、メモリ使用量が 25MB から >750MB に上昇したことです。アプリはARCを使用しているため、ここで少し迷っています。誰でもこれを解決する方法の手がかりはありますか?

NSFileHandle *fileStd = [stdPipe fileHandleForReading];

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: cmd];
[task setArguments: arguments];

NSPipe *stdPipe = [NSPipe pipe];
NSPipe *errPipe = [NSPipe pipe];

[task setStandardOutput: stdPipe];
[task setStandardError: errPipe];

NSFileHandle *fileStd = [stdPipe fileHandleForReading];

[task launch];

NSData *readData;
NSString *logString;

while ((readData = [fileStd availableData]) && [readData length]){

   logString = [[NSString alloc] initWithData: readData encoding: NSUTF8StringEncoding];
        [self parseLog:logString];
    }

    readData = nil;
}

[task waitUntilExit];

そして parseLog メソッド:

+ (void) parseLog:(NSString *)output {

    NSArray *chunks = [output componentsSeparatedByString: @"\r"];
    NSString *lastLine = [chunks lastObject];

    [lastLine writeToFile:@"/tmp/status.log" atomically:YES encoding:NSUTF8StringEncoding error:nil];

    NSRange textRange = [lastLine rangeOfString:@"<TEST> "];
    if(textRange.location != NSNotFound) {

        NSMutableDictionary *info = [NSMutableDictionary dictionary];
        [info setObject:lastLine forKey:@"test"];

        [[NSNotificationCenter defaultCenter] postNotificationName:@"handleNotification" object:nil userInfo:info];
    }
}
4

2 に答える 2

4

Allocations Instrument を使用して、ヒープが増加している理由を確認します。

特に、ヒープショット分析を使用すると、このような問題を非常に効率的に把握できます。

ここに書き込みがあります。

要するに:

  • Allocations Instrument の下でアプリを起動します
  • (1)マーク山ボタンを押す
  • しばらく待ってください
  • 後藤 (1)

それをしばらく繰り返します。あなたの場合、20 分から 1 時間に 1 回、マーク ヒープボタンを押すことをお勧めします。


ジェレミーはほぼ正解した。ループを少し再構築する必要があります。

while (1) {
@autoreleasepool {
   if (readData = [fileStd availableData]) && [readData length]){

   logString = [[NSString alloc] initWithData: readData encoding: NSUTF8StringEncoding];
        [self parseLog:logString];
    }

    readData = nil;
   } else {
    break;
   }
}

readDataプールにいる必要があります。

于 2013-07-16T15:51:25.000 に答える