0

私の同僚と私は、この問題を理解しようとすると、時間のキラーを抱えています。ファイル(カスタムメイドの3Dオブジェクトファイル)を解析したいと思います。問題は、fread、fseekなどのstdio関数呼び出しを使用することです。

以下のコードでは、呼び出し前と呼び出し後に仮想メモリをチェックすると、関数を実行するたびに1MBのように失われ、なぜこれが発生するのかわかりません。

FILE *fp= fopen([path UTF8String], "rb");
char *buffer = (char *) malloc(MAX_STRING_LENGTH);
while(!feof(fp))
{
    fgets(buffer, MAX_STRING_LENGTH, fp);
}

if(0 == fclose(fp))
    NSLog(@"File is closed");

free(buffer)

パスはiosライブラリから生成され、MAX_STRING_LENGTHは任意の数(例:2000000)です。

また、例ではhttp://www.cplusplus.com/reference/clibrary/cstdio/fread/の関数を使用しましたが、それでもメモリエラーが続きます。

バッファを作成して解放するだけではメモリは使用されないため、バッファは問題ではないことを知っていますが、whileループを使用すると、ファイルを閉じて使用可能なメモリを確認した後、以前より1MB少なくなります。 。この1週間、私と同僚はこれを修正しようと夢中になっています。

編集::

- (float)print_usage_memory
{    
vm_statistics_data_t vmStats;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);

const int availablePages = vmStats.free_count;
float availableMemory = [self pagesToMB:availablePages];

/*
 */     
const int totalPages = vmStats.wire_count + vmStats.active_count + vmStats.inactive_count + vmStats.free_count;
const int activePages = vmStats.active_count;
const int wiredPages = vmStats.wire_count;
const int purgeablePages = vmStats.purgeable_count;   

NSMutableString* txt = [[NSMutableString alloc] initWithCapacity:512];
[txt appendFormat:@"\nTotal: %d (%.2fMB)\n", totalPages, [self pagesToMB:totalPages]];
[txt appendFormat:@"                              nAvailable: %d (%.2fMB)\n", availablePages, availableMemory];
[txt appendFormat:@"                                 nActive: %d (%.2fMB)\n", activePages, [self pagesToMB:activePages]];
[txt appendFormat:@"nWired: %d (%.2fMB)\n", wiredPages, [self pagesToMB:wiredPages]];
[txt appendFormat:@"nPurgeable: %d (%.2fMB)\n", purgeablePages, [self pagesToMB:purgeablePages]];

NSLog(@"%@", txt);
[txt release];
txt = nil;

return availableMemory;
}


- (float)pagesToMB:(const int)pages
{
    return pages*4/1024;
}

あなたが与えることができるかもしれないどんな助け、またはこれへのどんな洞察にも感謝します。

4

2 に答える 2

0

いくつかの考え:

  1. テストをループで実行している場合は、ループ内の自動解放プールを必ず排出してください。そうしないと、テストが終了するまで排出されず、測定値が台無しになります。例えば:

    for(int i = 0; i < TEST_COUNT; i++)
    {
        // If you're using ARC, you can instead replace this with an
        // @autoreleasepool block
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        run_my_fopen_fgets_fclose_test();
        [pool release];
    }
    
  2. オブジェクトを開いた直後にオブジェクトを呼び出しsetbuf(fp, NULL)て、バッファなしのI/Oを使用してみてください。FILE*通常、stdioは、バッファを割り当ててデータをバッファリングしmalloc、ファイルデータを大きなチャンクで読み取ることができるようにします。このバッファはfree、を呼び出すと割り当てが解除されますfclose。ファイルを閉じているので、これがリークすることはないはずですが、メモリ測定に問題がある場合に備えて、バッファなしのI/Oを使用してよりクリーンな結果を得る価値があるかもしれません。

于 2012-11-12T17:00:15.433 に答える
0

私たちはそれを理解したと思います。問題は、iOSが使用する自動解放プールにあります。これは、必要なときに、アプリケーションがオフになっているとき、または解放用に設定されたメモリを実際に解放する必要があるときに、実際にメモリを解放します。ほぼ元の状態(たとえば、230mbで始まり、現在は225)に低下した後(残り約3mb)に大量のメモリを取り戻した後、それに気づきました。これは奇妙なバグでした。リリースのマークが付けられていないときにすべてがリリースされ、必要に応じて実際にリリースされると予想していたからです。

于 2012-11-13T15:29:05.690 に答える