Bug 11447 - Images/Streams? not being released from memory when disposed
Summary: Images/Streams? not being released from memory when disposed
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.3.x
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-03-27 13:02 UTC by Nathan Scavezze
Modified: 2013-03-27 20:12 UTC (History)
4 users (show)

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


Attachments
Test App (6.06 MB, application/zip)
2013-03-27 13:02 UTC, Nathan Scavezze
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 Nathan Scavezze 2013-03-27 13:02:58 UTC
Created attachment 3706 [details]
Test App

In my main app this bug was crashing sgen with a error but I cannot get it to happen in the test app instead the app just creates images until it dies.

Instruments showed it having  around 23500 Images and 23500 NSConcreteMutableData.  when it crashes 

basically my app creates 100 images then calls dispose on them then creates 100 more.
Comment 1 Sebastien Pouliot 2013-03-27 14:06:39 UTC
That's on device ? if so which model and iOS version ? I'll try to duplicate it with the closest hardware I have.

Also are you using the 6.3 *alpha* or the stable 6.2.x release ?
Comment 2 Rolf Bjarne Kvinge [MSFT] 2013-03-27 18:01:45 UTC
iOS requires you to use an NSAutoreleasePool.

This is done automatically on the main thread if you yield control once in a while, but you have to do it yourself on secondary threads. With the following change memory usage stays stable: https://gist.github.com/rolfbjarne/ff29730f74a6b8f5bcb1

Leaving the bug open since there may be a way we can avoid the NSAutoreleasePool for this particular case (still need to look into that).
Comment 3 Nathan Scavezze 2013-03-27 18:25:29 UTC
any device even the simulator.  the autorelease pool works I will try and figure out were to place that in my main app see if it helps.  I am using the latest none beta  of mono
Comment 4 Nathan Scavezze 2013-03-27 18:41:40 UTC
also I am not super familiar with NSAutoreleasePool.  typically were would these need to be used  and why?
Comment 5 Rolf Bjarne Kvinge [MSFT] 2013-03-27 19:11:28 UTC
Typically you may need to use an NSAutoreleasePool when you allocate/use/free objects in a loop. This is because iOS/Objective-C delay object disposal until the stack is unwound (technically they call the 'autorelease' method on the object, which will call the actually 'release' method once the stack is unwound and the first NSAutoreleasePool is encountered/freed).

Example:

while (true) {
    // create image
    // use image
    // free image
}

this is bad, because if iOS ever calls 'autorelease' on the image, it will never be freed, because no NSAutoreleasePool will ever be encountered since the stack is never completely unwound.

Compare with this:

while (true) {
    using (var pool = new NSAutoreleasePool ()) {
        // create image
        // use image
        // free image
    }
}

now for every image created there will be an NSAutoreleasePool on the stack, and just after the image has been freed the NSAutoreleasePool will be freed too (which, as mentioned ealier, will execute any pending 'release' calls on the image).

There is more information here: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html
Comment 6 Rolf Bjarne Kvinge [MSFT] 2013-03-27 20:12:53 UTC
Found a solution that doesn't require you to use an NSAutoreleasePool manually.

maccore: b164f95cc7e4dac10db718e819518e6951b9bdf8
monotouch:  f3bfc7f738c141664417959c29f31348b63b3f72