Hi Folks, I've been hunting memory leaks in a large application for my company (shame on Adobe for not putting in an option for weak references in ChangeWatchers!) and have noticed something. If you use a binding or changeWatcher or standard event listener on a popUpWindow, you of course get a nasty memory leak. However, I'm finding that even if you avoid such things, popping up and closing a window continuously does in fact cause a very slight but very real memory leak over time.
Running the following application over ten minutes shows a rise in about five megs of memory. Can anyone confirm that they've seen something like this? Is this something that just has to be lived with, or is there a way to ensure that standard use of the flex components doesn't cause leaks? <!-- MyApp.mxml --> <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" creationComplete="addObject()" layout="vertical"> <mx:Script> <![CDATA[ import mx.containers.TitleWindow; import mx.managers.PopUpManager; import flash.utils.setTimeout; public var popUps:Array = [] public function addObject():void { var dialog:TitleWindow = new TitleWindow(); PopUpManager.addPopUp(dialog,this); popUps.push(dialog); setTimeout(removeAllObjects,50); } public function removeAllObjects():void { for each(var item:TitleWindow in popUps){ PopUpManager.removePopUp(item); } popUps = []; setTimeout(addObject,50); } ]]> </mx:Script> <local:MemoryMonitor id="mm" creationComplete="mm.start()" width="100%" /> </mx:Application> <!-- MemoryMonitor.mxml --> <?xml version="1.0" encoding="iso-8859-1"?> <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; private var timer:Timer; private var maxmem:Number = 0; private var lasttotal:Number = 0; private var initYet:Boolean = false; private var startTime:Number = new Date().getTime(); private var startBytes:Number = System.totalMemory; [Bindable] private var seriesArray:ArrayCollection=new ArrayCollection([]); private var counter:int=0; public var maxPoints:Number = 100; private function fullGC():void { // unsupported hack that seems to force a full GC try { var lc1:LocalConnection = new LocalConnection(); var lc2:LocalConnection = new LocalConnection(); lc1.connect('name'); lc2.connect('name'); } catch (e:Error) { } } private function timerHandler(event:Event):void { var totalmem:Number = System.totalMemory; lasttotal = totalmem; total.text = totalmem.toString(); maxmem = Math.max(maxmem, System.totalMemory); max.text = maxmem.toString(); if(counter++%10==0){ fullGC(); setMin(); } seriesArray.addItem({time:new Date().getTime(), value:totalmem}); var len:int = seriesArray.length; if(len>=maxPoints){ var rand:Number = Math.random(); // remove a fairly recent random point var index:int = Math.floor((1-rand*rand*rand)*(maxPoints-1)); seriesArray.removeItemAt(index+1); } if (callbackFunction != null) callbackFunction(); } private function setMin():void { var min:Number = -1; for each(var item:Object in seriesArray){ if(min==-1) min = item.value; else if (min>item.value) min = item.value; } LinearAxis(chart.verticalAxis).minimum = min; } public var interval:int = 100; public var callbackFunction:Function = null; public function start():void { timer = new Timer(interval); timer.addEventListener("timer", timerHandler); timer.start(); } public function stop():void { timer.stop(); timer.removeEventListener("timer", timerHandler); timer = null; } ]]> </mx:Script> <mx:HBox> <mx:Label text="current memory:" /> <mx:Label id="total" text="0" width="100" /> <mx:Spacer width="20" /> <mx:Label text="max memory:" /> <mx:Label id="max" text="0" width="100" /> <mx:Spacer width="20" /> <mx:Button label="resetChart" click="seriesArray.removeAll()" /> </mx:HBox> <mx:LineChart id="chart" height="100" width="100%" showDataTips="true" > <mx:horizontalAxis> <mx:DateTimeAxis /> </mx:horizontalAxis> <mx:verticalAxis> <mx:LinearAxis /> </mx:verticalAxis> <mx:series> <mx:LineSeries dataProvider="{seriesArray}" xField="time" yField="value"/> </mx:series> </mx:LineChart> </mx:VBox>