Hello Matthieu, On Sun, Aug 5, 2012 at 2:34 PM, Matthieu Laban <[email protected]> wrote: > Hello Guys, > > My quest for leaks continues... I'm downloading files from our server, and > the size of the files can vary between 1 and 20 MB. > The issue is that after the file is downloaded, the app's dirty size goes up > ~20MB and never goes down even if I dispose the WebClient, remove all event > listeners and call GC.Collect().
The easiest way to reduce your dirty memory [1] is to reduce your allocations [2]. [1] http://stackoverflow.com/q/5176074/220643 [2] http://stackoverflow.com/q/6471435/220643 > If I run the download code a few times, it climbs 20 MB about 3x, then it > stops even if I call it again. This is not a leak. A leak is something (memory, resources) that, after being used, cannot be re-used anymore. > Is there some kind of cache that is being > maintained or something? The fact that it gets reused suggest caching, but it's likely very deep down (e.g. mono's own memory pools). > How can I make sure some of that memory is > reclaimed. We're tight on memory on the iPod Touch and we'd love to get some > of it back :) I suggest a small change of design to minimize your memory requirements: 1. Avoid keeping data in memory. 1.1. The ZIPped data is likely not useful to keep around, i.e. it won't be used until decompressed (into one or several files), but even if it was... 1.2. The 20MB download may take quite some time (e.g. cellular) and you do not want to hold on to large memory blocks for long times (e.g. be nice to other running applications); 2. Keep using WebClient as it is simpler than HttpWebRequest - but instead of using DownloadData use DownloadFile [1] to a temporary location. That will download your ZIP file in chunks of 32KB, lowering your app memory requirements, and the file can be decompressed later (e.g. using streams to avoid loading it into memory) and then deleted. Speaking of streams an alternative would be use a OpenRead to get a Stream and process data, in small chunks, as it comes in. You get more control this way (if you need it) but you'll likely end up duplicating DownloadFile. [1] https://github.com/mono/mono/blob/mono-2-10/mcs/class/System/System.Net/WebClient.cs#L299 Regards, Sebastien > Here's the code that I'm running: > > void DoStuff() > { > WebClient client = new WebClient(); > client.DownloadProgressChanged += client_DownloadProgressChanged; > client.DownloadDataCompleted += client_DownloadDataCompleted; > client.DownloadDataAsync(new > Uri("http://ipv4.download.thinkbroadband.com/20MB.zip")); > } > > void client_DownloadDataCompleted(object sender, > DownloadDataCompletedEventArgs e) > { > var webClient = sender as WebClient; > webClient.DownloadDataCompleted -= client_DownloadDataCompleted; > webClient.DownloadProgressChanged -= client_DownloadProgressChanged; > webClient.Dispose(); > webClient = null; > GC.Collect(); > GC.WaitForPendingFinalizers(); > MessageBox.Show("Completed"); > } > > -- > Matt > > > _______________________________________________ > MonoTouch mailing list > [email protected] > http://lists.ximian.com/mailman/listinfo/monotouch > _______________________________________________ MonoTouch mailing list [email protected] http://lists.ximian.com/mailman/listinfo/monotouch
