2012-04-30 10 views
1

wikiのサンプルコードをテストしましたが、libdispatchがOS X(Lion 10.7.3、Xcode 4.3.2)とLinux手動でコンパイルしてインストールします)。libdispatchのメモリに関する問題

このコードは、SIGHUPシグナルソースを作成し、ログファイルに100_000の書き込みを呼び出すハンドラを使用します。ログへの書き込みは、シリアルキューに入れられます。

最初の実行では、通常のメモリ使用量が表示されます(8-9 MiBはLinuxとOS Xの両方)。 「kill -1」を送信すると、SIGHUP信号を送信するたびにメモリ使用量が1〜20MiB増加します。

私は-fobj-arcでコンパイルしようとしましたが、コンパイルしていないのですが、結果は同じです。私はbr_log関数でNSStringの使用法を削除しましたが、リークはありません。libdispatchのどこかにあります。

私はvalgrindとXcode Instrumentsの両方を試しましたが、リークは見つかりませんでした。おかげさまで、

// 
// main.m 
// test02 
// 
// Created by Aldrin Martoq on 4/29/12. 
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 
// 

#include <unistd.h> 
#import <Foundation/Foundation.h> 
#import <dispatch/dispatch.h> 

static FILE *log_file = NULL; 
static NSString *log_filename = @"/tmp/br.log"; 
static dispatch_queue_t log_queue; 


void br_log(NSString *format, ...) { 
    @autoreleasepool { 
     va_list ap; 
     va_start(ap, format); 
     NSString *s = [[NSString alloc] initWithFormat:format arguments:ap]; 
     va_end(ap); 

     if (log_file == NULL) { 
      log_queue = dispatch_queue_create("cl.martoq.log_queue", NULL); 

      log_file = fopen([log_filename cStringUsingEncoding:NSUTF8StringEncoding], "a"); 
      NSLog(@"Log file created: %@", log_filename); 
     } 

     dispatch_async(log_queue, ^{ 
      @autoreleasepool { 
       const char *c = [s cStringUsingEncoding:NSUTF8StringEncoding]; 
       fputs(c, log_file); 
       fputs("\n", log_file); 
       fflush(log_file); 
       [s release]; 
      } 
     }); 
    } 
} 

void br_setup() { 
    signal(SIGHUP, SIG_IGN); 
    dispatch_source_t sig_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGHUP, 0, dispatch_get_main_queue()); 
    dispatch_source_set_event_handler(sig_src, ^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      printf("Caught SIGHUP\n"); 
      for (int i = 0; i < 100000; i++) { 
       br_log(@"prueba: %d", i); 
      } 
     }); 
    }); 
    dispatch_resume(sig_src); 
} 


int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     // insert code here... 
     NSLog(@"Hello, World!"); 
     br_setup(); 
     dispatch_main(); 
    } 
    return 0; 
} 

答えて

0

どのようにこのメモリ使用量の増加を測定していますか?私は 'ヒープ'ツールを使ってMac OS Xでそれを再現することはできません。

libdispatch継続キャッシュの一時的な影響を見ることができます。これらは、各dispatch_async()に対して割り当てられ、速度のためにスレッドごとにキャッシュされる小さなバッファです。そのキャッシュは、一時的なディスパッチワーカースレッドが終了すると解放されます(例ではSIGHUPの後、Mac OS Xでは少なくとも2,3秒後にキャッシュが解放されます)。あなたはその時点でメインキュー上に既にあるので、

はまたところで、あなたはすでにについて尋ねてきた

(元のターゲット・キュー)ソースイベントハンドラから)(dispatch_asyncする必要がないことに注意してくださいこれは[email protected]にありますが、私はそこで反応しました。複数のフォーラムで同じ質問を同時にしないでください。