Контроль за ресурсами. Первое знакомство с flash.sampler
В первом блоге я написал, то что многим, в общем, уже было известно.
Моей конечная цель, если вы еще не знаете, написать своеобразный менеджер проекта, одной из функций которого будет профилирование моего проекта present-simple.ru
Сегодня я попробую познакомить вас с библиотекой flash.sampler.* Эта библиотека очень поможет, в решении моей задачи.
Я попробую показать эту библиотеку в действии на одном конкретном примере, думаю так будет проще и нагляднее.
Для демонстрации свойств flash.sampler нам понадобится сама библиотека, а также
два таймера. Один таймер будет запускать функцию, которая будет добавлять при каждом заходе новый спрайт и помещать на сцену, другой таймер будет запускать
функцию собирающую образы (samples) для профилирования проекта.
В этом примере нашей целью будет зафискировать, что объекты при вызове сборщика мусора действительно удаляются из памяти
Итак начнем:
import flash.display.* import flash.sampler.* import flash.events.* import flash.utils.Timer; import flash.utils.getQualifiedClassName; import flash.system.System; public class Main extends Sprite { // создаем ссылки на таймеры private var update:Timer; private var sampling:Timer; // стандартная точка входа: public function Main() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } public function init () :void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point pauseSampling (); // создаем таймер для объектов отображения update = new Timer (500, 11); update.addEventListener (TimerEvent.TIMER, updateTimer); update.addEventListener (TimerEvent.TIMER_COMPLETE, updateComplete); update.start (); // второй таймер будет работать по стопам первого поэтому запустим его // через еще один временный таймер var startSampling:Timer = new Timer (50, 1); startSampling.addEventListener (TimerEvent.TIMER_COMPLETE, onStartSampling); startSampling.start (); } public function onStartSampling (event:TimerEvent) :void { startSampling (); sampling = new Timer (500, 11); sampling.addEventListener (TimerEvent.TIMER, scaningTimer); sampling.addEventListener (TimerEvent.TIMER_COMPLETE, onScaningComplete); sampling.start (); } }
Теперь создадим обработчики событий наших таймеров:
private function updateTimer (event:TimerEvent) :void { create (); } // в этом методе мы будем создавать наши спрайты. Я немного нагрузил эту функцию, //чтобы было чуть веселее, и пусть это прибавит нам образов, мы не станем //зацикливать на них наше внимание. private function create () :void { var sprite:Sprite = new Sprite (); var color:uint = Math.round ( Math.random () * 0xFFFFFF); sprite.graphics.beginFill (color, 1); sprite.graphics.drawCircle (10, 10, 20); sprite.graphics.endFill (); sprite.x = 50 + Math.round ( Math.random () * 500); sprite.y = 50 + Math.round ( Math.random () * 300); sprite.name = 'sprite_' + this.numChildren; this.addChild (sprite); }
теперь функция сборщик образов
private function scaningTimer (event:TimerEvent) :void { pauseSampling (); trace ('**********************itteration ' + itterationCof++); var samples:* = getSamples (); var samplesCount:int = 0; for each ( var sample:* in samples) { if (sample is NewObjectSample) { catchNewSample (sample, samplesCount); samplesCount ++; continue; } else if (sample is DeleteObjectSample) { catchDeleteSample (sample, samplesCount); samplesCount ++ continue; } else { catchSample (sample, samplesCount); samplesCount ++; } } clearSamples (); startSampling (); }
Я добавил еще три внутренних функции в одной мы будем отлавливать образы, информирующие о создании новых объектов. Во второй информации об удалении объектов из памяти. И в третьей внутренние события FlashPlatform
private function catchNewSample (sample:NewObjectSample, actionsCount:int) :void { trace ('action ' + actionCount + ' : ' + 'newObjectSample cathced'); /* в объекте newObjectSample помимо стека вызовов функции (хранится в свойстве stak) и свойстве time есть еще два важных метода id и object (недокументированное свойство) именно это и послужит опорой для определения того, будут ли наши спрайты или удалены после вызова сборщика мусора */ // это проверка нужна для отсеивания образов без ссылок на объекты (объекты созданные средой Flash) if (sample['object'] != null && sample['object'] != undefined) { // определяем id var id:int = sample.id; // определяем ссылку на созданный объект var obj:Object = sample['object']; // теперь определим к какому классу относится объект: var classDescription:String = getQualifiedClassName (object); // поскольку я хочу зафискировать в данном примере только то, что происходит со спрайтами // я отфильтрую все образы, объекты которого не относятся к 'flash.display::Sprite'; // После этого я помещу их в свое личное временное хранилище (определите ему любое имя - это // должен быть простой объект, добавленный в свойство класса Main). У меня это cache if (!cache) cache = new Object (); // Чтобы легче было идентифицировать наши спрайты я создал простой класс SpriteDescription у // которого будет одно свойство name (позже мы можем его расширить и добавить еще что - нибудь полезное) if (classDecription == 'flash.display::Sprite') { var name:String = (obj as Sprite).name cache[id] = new SpriteDescription (name); } } }
private function deleteNewSample (sample:DeleteObjectSample, actionsCount:int) :void { trace ('action ' + actionCount + ' : ' + 'deleteObjectSample cathced'); // в пойманном образе по свойству id удаленного из памяти объекта мы сможем определить, что это был за // поскольку в нашем кеше есть описание этого объекта, которое мв сможем найти по тому же id var id = sample.id if (cache[id] != null) { var description:SptiteDescription = cache[id] cache[id] = null; // я объявил еще один массив в публичных свойствах чтобы выдать все SpriteDescriptions одним списком descrArr.push (description); } }
private function catchSample (sample:Sample, actionsCount:int) :void { // эта функция в контексте нашего кода вызывается в том слкучае, если образ (sample) не является объектом // NewObjectSample и DeleteObjectSample, в массиве stack таких образов хранятся внутренние события плеера // (internal actions), но это тема для отдельной дискуссии поэтому оставим пока тело функции пустым }
Теперь как осталось только дописать два заключительных метода, завершающих работу таймеров
private function updateComplete (event:TimerEvent) :void { // просто удалим все объекты со сцены (и таким образом потеряем ссылки на них) и вызовем сборщик мусора while (this.numChildren) removeChildAt (0); System.gc (); } private function onScaningComplete (event:TimerEvent) :void { trace (************************ Finaly ******************); // выведем список всех убитых спрайтов for each (var description:SpiteDecription in descrArr) { trace (description); } }
Всего комментариев 3
Комментарии
![]() ![]() |
|
Нет это объект Sample и наследуемые от него NewObjectSample и DeleteObjectSample
|
Последние записи от inozemcev
- Контроль за ресурсами. Первое знакомство с flash.sampler (28.11.2010)
- present - simple. Часть I. Контроль за ресурсами. (17.11.2010)