fixed potential memory leak in AssetManager.loadQueue that would prevent the calling object from garbage collection#776
fixed potential memory leak in AssetManager.loadQueue that would prevent the calling object from garbage collection#776soccerob wants to merge 2 commits intoGamua:masterfrom
Conversation
I'm not sure why this is a problem, but I spent all morning tracking down a small memory leak and was able to trace it to this. The expected behavior of the variable "onProgress", is that it would lose scope and lose its reference from the calling object as soon as the loadQueue method completes, but for some reason when loading remote assets, it doesn't.
When loading remote assets (http://<some-asset.mp3>), a reference is kept to the calling class's onProgress method which prevents the calling class from being garbage collected.
example: SampleClass will not be garbage collected because a reference to "reportProgress" exists in AssetManager
class SampleClass {
function beginLoading():void {
function reportProgress(ratio:Number):void {
if (ratio >= 1.0) {
doSomething();
}
}
assetManager.enqueue(<my-mp3-file.mp3>);
assetManager.loadQueue(reportProgress);
}
}
|
oops, messed something up. fixing... |
removed an incorrect line setting onProgress = null inside cancel()
|
Would it cause any problems to call cancel() after onProgress(1.0) example: function cancel():void
{
removeEventListener(Event.CANCEL, cancel);
mNumLoadingQueues--;
canceled = true;
onProgress = null;
}
function finish():void
{
setTimeout(function():void
{
if (!canceled)
{
onProgress(1.0);
cancel();
}
}, 1);
} |
|
Thanks a lot for the report, and for the attempt to fix it! Hm ... that's really weird. I can reproduce the issue, but I simply cannot understand why the I first thought that it's maybe the "setTimeout" calls, because I'm not properly calling "clearTimeout". But that doesn't change anything. Event listeners seem to always be correctly removed. Very odd! In any case, moving the "cancel" call above "onProgress" is not ideal, because people might start a new queue directly from the callback; and this wouldn't work any longer, then. A working fix would be the following: function cancel():void
{
removeEventListener(Event.CANCEL, cancel);
mNumLoadingQueues--;
canceled = true;
onProgress = null;
}
function finish():void
{
setTimeout(function():void
{
if (!canceled)
{
var progressFunc:Function = onProgress;
cancel();
progressFunc(1.0);
}
}, 1);
}I haven't committed the change yet, though — I want to sleep over it, perhaps I can find the original issue, after all. ... or does anyone else have a clue? |
I'm not sure why this is a problem, but I spent all morning tracking down a small memory leak and was able to trace it to this. The expected behavior of the variable "onProgress", is that it would lose scope and lose its reference from the calling object as soon as the loadQueue method completes, but for some reason when loading remote assets, it doesn't.
When loading remote assets (http://<some-asset.mp3>), a reference is kept to the calling class's onProgress method which prevents the calling class from being garbage collected.
example: SampleClass will not be garbage collected because a reference to "reportProgress" exists in AssetManager