Re: [MonoTouch] WebClient memory issues

2012-08-06 Thread Matthieu Laban
On Mon, Aug 6, 2012 at 5:37 AM, Sebastien Pouliot sebast...@xamarin.comwrote:

 Hello Matthieu,

 On Sun, Aug 5, 2012 at 2:34 PM, Matthieu Laban
 m...@flyingdevelopmentstudio.com 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


Yup, we've already been reducing allocations a lot. Thanks for the links :)


  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...


I'd love to but I never even access the byte[] that has been downloaded in
this case.

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);


After watching the talk at WWDC 2012 on memory, that's the thing I'm trying
to do now, avoid spikes of memory allocations.



 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


Thanks, I'll try these. I think I had tried one of those in the past but
the progress event was never fired, so I had to switch to a different
method.


--
Matt
___
MonoTouch mailing list
MonoTouch@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/monotouch


Re: [MonoTouch] WebClient memory issues

2012-08-06 Thread Matthieu Laban
Using DownloadFile instead of DownloadData did solve my problem. Memory
usage is staying low and I don't see many allocations being done during the
download.

Thanks again for your help,
Matt

On Mon, Aug 6, 2012 at 8:55 AM, Matthieu Laban 
m...@flyingdevelopmentstudio.com wrote:



 On Mon, Aug 6, 2012 at 5:37 AM, Sebastien Pouliot 
 sebast...@xamarin.comwrote:

 Hello Matthieu,

 On Sun, Aug 5, 2012 at 2:34 PM, Matthieu Laban
 m...@flyingdevelopmentstudio.com 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


 Yup, we've already been reducing allocations a lot. Thanks for the links :)


  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...


 I'd love to but I never even access the byte[] that has been downloaded in
 this case.

 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);


 After watching the talk at WWDC 2012 on memory, that's the thing I'm
 trying to do now, avoid spikes of memory allocations.



 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


 Thanks, I'll try these. I think I had tried one of those in the past but
 the progress event was never fired, so I had to switch to a different
 method.


 --
 Matt

___
MonoTouch mailing list
MonoTouch@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/monotouch


[MonoTouch] WebClient memory issues

2012-08-05 Thread Matthieu Laban
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().
If I run the download code a few times, it climbs 20 MB about 3x, then it
stops even if I call it again. Is there some kind of cache that is being
maintained or something? 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 :)

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
MonoTouch@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/monotouch