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

Reply via email to