|
|
|||||
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Можно ли вычистить XML из памяти?
Собственно, несложный тест показывает, что присвоение null ничего не дает:
package { import flash.display.Sprite; import flash.events.Event; import flash.system.*; public class Main extends Sprite { private var testXML:XML; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point checkMemory("before init testXML:"); testXML = generateXML(); checkMemory("after init testXML:"); testXML = null; checkMemory("after testXML=null:"); } private function checkMemory(label:String) : void { System.gc(); trace("Main::checkMemory", label, System.totalMemory); } private function generateXML() : XML { var xml:XML = new XML(); for (var i:int = 0; i < 1000; i++) { var child:XML = XML('<random/>'); child.@value = Math.random(); xml.appendChild(child) } return xml; } } } |
|
|||||
Цитата:
http://help.adobe.com/en_US/as3/mobi...7189-7ffc.html |
|
|||||
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Это, конечно, удивительно, но замена присвоения нулла на System.disposeXML(testXML) не дала ничего.
Добавлено через 43 секунды Main::checkMemory before init testXML: 3371008 Main::checkMemory after init testXML: 4550656 Main::checkMemory after System.disposeXML(testXML): 4550656 Не, не удивительно. Это же принудительный вызов GC для режима выполнения, а в режиме отладки GC и так вызывается. |
|
|||||
Попробуйте проверять количество памяти через несколько "фреймов". Кто его знает, как устроен сборщик мусора, может он делает это поэтапно...
Вот тут, нужно покликать по черному квадрату, чтобы запустить gc. Если закомментировать disposeXML, и присвоение null, памяти больше занимает. package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.net.URLLoader; import flash.net.URLRequest; import flash.system.System; import flash.utils.Timer; /** * @author zu */ public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private var data:XML; private function init(e:Event = null):void { var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.COMPLETE, loadComplete); loader.load(new URLRequest('test.xml')); var sprite:Sprite = new Sprite(); sprite.graphics.beginFill(0); sprite.graphics.drawRect(0, 0, 200, 200); sprite.graphics.endFill(); addChild(sprite); sprite.addEventListener(MouseEvent.CLICK, testMemoryListener); } private function testMemoryListener(e:Event):void { System.gc(); trace(System.totalMemory); if (data) { System.disposeXML(data); data = null; } } private function loadComplete(e:Event):void { data = new XML(URLLoader(e.currentTarget).data); e.currentTarget.removeEventListener(e.type, arguments.callee); } } } |
|
|||||
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Опытным путем установлено, что System.disposeXML() работает, хотя и несколько парадоксально. Он действительно требует времени на свою работу и чистит не до конца.
package { import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.system.*; import flash.utils.*; public class Main extends Sprite { private var testXML:XML; private var testBitmapData:BitmapData; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point checkMemory("before init testXML:"); testXML = generateXML(); checkMemory("after init testXML:"); System.disposeXML(testXML); System.gc(); checkMemory("after disposeXML(testXML) immediately:"); setTimeout(checkAfterTimeout, 1000); } private function checkMemory(label:String) : void { trace("Main::checkMemory", label, System.totalMemory/1024); } private function checkAfterTimeout() : void { checkMemory("after disposeXML(testXML) and timeout:"); } private function generateXML() : XML { var xml:XML = new XML(); for (var i:int = 0; i < 10000; i++) { var child:XML = XML('<random/>'); child.@value = Math.random(); xml.appendChild(child) } return xml; } } } |
|
|||||
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Вот как бы нет.
package { import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.system.*; import flash.utils.*; public class Main extends Sprite { private var testXML:XML; private var testBitmapData:BitmapData; private var timer:Timer; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point checkMemory("before init timer:"); timer = new Timer(5000, 1) timer.addEventListener(TimerEvent.TIMER, checkAfterTimeout); checkMemory("after init timer:"); testXML = generateXML(); checkMemory("after init testXML:"); System.disposeXML(testXML); System.gc(); checkMemory("after disposeXML(testXML) immediately:"); timer.start(); } private function checkMemory(label:String) : void { trace("Main::checkMemory", label, System.totalMemory/1024); } private function checkAfterTimeout(e:Event) : void { checkMemory("after disposeXML(testXML) and timeout:"); } private function generateXML() : XML { var xml:XML = new XML(); for (var i:int = 0; i < 10000; i++) { var child:XML = XML('<random/>'); child.@value = Math.random(); xml.appendChild(child) } return xml; } } } Main::checkMemory before init timer: 3336 Main::checkMemory after init timer: 3356 Main::checkMemory after init testXML: 4416 Main::checkMemory after disposeXML(testXML) immediately: 4416 Main::checkMemory after disposeXML(testXML) and timeout: 3628 Кстати, если процедуру генерации слегка изменить: private function generateXML() : XML { var xml:XML = <testXML/>; for (var i:int = 0; i < 10000; i++) { var child:XML = <random/>; child.@value = Math.random(); xml.appendChild(child) } return xml; } |
|
|||||
Один из клиентов ругался на рост пожираемой памяти. Выяснили, что хмл не убивается, а они у нас от 16 метров и больше. Пришлось переходить на 11 плеер. disposeXML разрушает хмл и этот "мусор" дальше ждет GC. Сейчас использую disposeXML и http://silin.su/#AS3/utils/gc в проекте (работает), жду пока откажемся от хмл.
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку. |
|
|||||
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Да, адобовцы свинью подложили еще ту.
Работать с xml реально удобно, но то, что он столько памяти на себя берет - это какая-то жесть. |
Часовой пояс GMT +4, время: 01:13. |
|
« Предыдущая тема | Следующая тема » |
Теги |
garbage collector , xml |
|
|