比较大文件时的内存泄漏(在ARC下)

时间:2014-12-04 09:02:36

标签: objective-c memory-leaks automatic-ref-counting

我想比较2个文件。当文件非常大时(我用1,7G测试),这个过程会不断增长,直到它停止为止。显然ARC并没有正确释放空间(或者客观的图书馆不会自行清理)。

在仪器中我看到" Malloc 4,0KB"有越来越高的Live Bytes - 直接指向NSFileHandle或NSData,因为我使用的是4096字节的缓冲区。

我已经尝试了很多不同的东西,比如每个循环初始化文件,并在每个循环结束时将它们设置为nil。什么都没有帮助。

有什么想法吗? NSAutoreleasePool会帮忙吗?

这是核心代码:

NSFileHandle *file1;
NSFileHandle *file2;

int bufferSize = 4096;

file1 = [NSFileHandle fileHandleForReadingAtPath: [self.input1 stringValue]];
file2 = [NSFileHandle fileHandleForReadingAtPath: [self.input2 stringValue]];

int long long size1 = [file1 seekToEndOfFile];
int long long size2 = [file2 seekToEndOfFile];
int long long pos1 = 0;
int long long pos2 = 0;

if(size1 != size2) {
    NSLog(@"Files have different sizes");
    return;
}

do {

    [file1 seekToFileOffset: pos1];
    [file2 seekToFileOffset: pos2];

    NSLog(@"Reading at: %lli",[file1 offsetInFile]);

    if(![[file1 readDataOfLength: bufferSize] isEqualToData: [file2 readDataOfLength: bufferSize]]) {
        break;
    }

    pos1 += bufferSize;
    pos2 += bufferSize;

} while(pos1 < size1);

if(pos1 < size1) {
    NSLog(@"Files do not match");
} else {
    NSLog(@"Files are an exact match");
}

1 个答案:

答案 0 :(得分:1)

正如我之前发生的那样,在发布问题后,我有了一些新的想法。

我用过

NSData initWithContentsOfFile: options: NSDataReadingMappedAlways error:nil

读取文件,而不是NSFile。现在它有效。

int bufferSize = 4096;

NSData *file1;
NSData *file2;
NSRange range1;
NSRange range2;
unsigned char buffer1[bufferSize];
unsigned char buffer2[bufferSize];

range1.length = bufferSize;
range2.length = bufferSize;
range1.location = 0;
range2.location = 0;

int long long size1 = [[[NSFileManager defaultManager] attributesOfItemAtPath: [self.input1 stringValue] error:nil] fileSize];
int long long size2 = [[[NSFileManager defaultManager] attributesOfItemAtPath: [self.input2 stringValue] error:nil] fileSize];


if(size1 != size2) {
    NSLog(@"Files have different sizes");
    return;
}

file1 = [[NSData alloc] initWithContentsOfFile:[self.input1 stringValue] options: NSDataReadingMappedAlways error: nil];
file2 = [[NSData alloc] initWithContentsOfFile:[self.input2 stringValue] options: NSDataReadingMappedAlways error: nil];

do {
    [file1 getBytes: buffer1 range: range1];
    [file2 getBytes: buffer2 range: range2];

    NSData *data1 = [[NSData alloc] initWithBytes: buffer1 length: bufferSize];
    NSData *data2 = [[NSData alloc] initWithBytes: buffer2 length: bufferSize];

    if (![data1 isEqualToData: data2]) {
        break;
    }

    NSLog(@"Reading: %i",(int)(((float)range1.location / (float)size1) * 10000) / 100);

    range1.location += bufferSize;
    range2.location += bufferSize;

} while(range1.location < size1);

if(range1.location < size1) {
    NSLog(@"Files do not match");
} else {
    NSLog(@"Files are an exact match");
}