Bug 15234 - Memory leak when getting to raw binary of saved photos
Summary: Memory leak when getting to raw binary of saved photos
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.0.0.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-10-06 18:31 UTC by dj_technohead
Modified: 2013-10-07 22:42 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Sample project showing memory leak (10.59 KB, application/zip)
2013-10-06 18:31 UTC, dj_technohead
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description dj_technohead 2013-10-06 18:31:09 UTC
When iterating through saved photos on a physical device and accessing the raw jpeg data, low memory warnings are raised and then the app crashes.

foreach(ALAsset asset in this.ListAssets)
{
	ALAssetRepresentation rep = asset.DefaultRepresentation;

	Console.WriteLine("Processing raw photos for image # " + idx++);


	// Memory leakage somewhere in this block of code
	using (CGImage cgi = rep.GetImage())
	{
		using (UIImage img = UIImage.FromImage(cgi))
		{
			using (NSData jpegData = img.AsJPEG())
			{
			}
		}
	}

	GC.Collect();

}
Comment 1 dj_technohead 2013-10-06 18:31:46 UTC
Created attachment 5075 [details]
Sample project showing memory leak
Comment 2 Sebastien Pouliot 2013-10-06 20:46:12 UTC
That sounds more like an autorelease pool is keeping data alive (than a leak). Try :

foreach(ALAsset asset in this.ListAssets) {
    using (var pool = new NSAutoreleasePool ()) {
       // existing code in the foreach
    }
}

and see if memory utilization stays constant. What the above code does is providing a new pool at every iteration of the loop (and drain the pool each time).

The monotouch.dll bindings already protects some API (by inserting pools where needed). OTOH we do not have one for `ALAssetRepresentation.GetImage` (which is my prime suspect right now). I'll confirm that tomorrow (with your sample) but the above workaround might help you until we ship a version that will do this automagically.
Comment 3 Sebastien Pouliot 2013-10-07 09:04:58 UTC
The above does fix the issue* and you can (and should) remove the `GC.Collect();` from the loop.

* I can process all 106 pictures I have on my device, without a single memory warning. Without the pool I got warnings in the 40th-ish pictures.
Comment 4 Sebastien Pouliot 2013-10-07 11:07:41 UTC
Moving the pool after `GetImage`, i.e.

	using (CGImage cgi = rep.GetImage()) {
		using (var pool = new NSAutoreleasePool ()) {

has the same issue, so `ALAssetRepresentation.GetImage` binding needs an [Autorelease] attribute.

Fixed in master 7360bf80ef227d26c163a5f4ca7f8f71bf84877c
Comment 5 dj_technohead 2013-10-07 22:42:41 UTC
OK thanks!