Hi Daniel, I'm using Activity Monitor (OS X) and top (linux). 1) Here we have 1.9MiB initially (no SIGHUP sent yet) http://cl.ly/2P1o3s3T0P1X0l1D390W 2) Here we have 147MiB while the loop is running (SIGHUP sent) http://cl.ly/473x2U1v2W1h1141441k 3) Here we have 24.7MiB after everything is done http://cl.ly/0n0S3K3t3n2C0t1y393l 4) If I send the signal again, memory increases everytime (26.0 MiB here) http://cl.ly/0B2E2g3V021f0s2w3T2v Memory never goes down after that, in Linux it is worst. Thanks for the note on dispatch_async(), It was not there originally… I was trying to make it work and adding autoreleasepools just in case, but nothing seemed to work ;) Regards, Aldrin Martoq A. http://aldrin.martoq.cl/ On Apr 30, 2012, at 3:07 PM, Daniel A. Steffen wrote:
Aldrin,
how are you measuring this memory usage growth? I cannot reproduce it on Mac OS X with the 'heap' tool
You might be seeing the temporary effects of the libdispatch continuation cache, these are small buffers that get allocated for each dispatch_async() and cached on a per-thread basis for speed. That cache is freed once a temporary dispatch worker thread exits ( a couple of seconds after SIGHUP in your example, on Mac OS X at least)
Also note that there is no need to dispatch_async() from your source event handler since you are already on the main queue at that point (the target queue of the source)
Daniel
On Apr 29, 2012, at 23:09, Aldrin Martoq Ahumada <aldrin.martoq@gmail.com> wrote:
Hi, I have been testing sample code from the wiki and found that libdispatch is alloc'ing a lot of memory without releasing it, both in OS X (Lion 10.7.3, Xcode 4.3.2) and Linux (manually compiled and installed).
The code creates a SIGHUP signal source, with a handler that calls 100_000 writes to a logfile. The write to a log is queued in a serial queue.
The first run shows normal memory usage (8-9 MiB both Linux and OS X). After sending a "kill -1 <pid>" memory usage increases 1-20MiB every time I send the SIGHUP signal.
I have tried compiling with -fobj-arc and without it, but the result is the same. I removed the NSString usage in the br_log function, but the leak is not there: it is somewhere inside libdispatch.
I tried both valgrind and Xcode Instruments, but no leaks are found. Thanks in advance,
---- ini ---- // // 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; } ---- fini ----
Aldrin Martoq A. http://aldrin.martoq.cl/
_______________________________________________ libdispatch-dev mailing list libdispatch-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev