Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > inozemcev

Оценить эту запись

Контроль за ресурсами. Первое знакомство с flash.sampler

Запись от inozemcev размещена 28.11.2010 в 22:08
Обновил(-а) iNils 30.11.2010 в 16:48

В первом блоге я написал, то что многим, в общем, уже было известно.

Моей конечная цель, если вы еще не знаете, написать своеобразный менеджер проекта, одной из функций которого будет профилирование моего проекта present-simple.ru

Сегодня я попробую познакомить вас с библиотекой flash.sampler.* Эта библиотека очень поможет, в решении моей задачи.

Я попробую показать эту библиотеку в действии на одном конкретном примере, думаю так будет проще и нагляднее.

Для демонстрации свойств flash.sampler нам понадобится сама библиотека, а также
два таймера. Один таймер будет запускать функцию, которая будет добавлять при каждом заходе новый спрайт и помещать на сцену, другой таймер будет запускать
функцию собирающую образы (samples) для профилирования проекта.

В этом примере нашей целью будет зафискировать, что объекты при вызове сборщика мусора действительно удаляются из памяти

Итак начнем:

Код AS3:
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 ();
   }
}
Если вы заметили мы уже вызвали две функции из библиотеки flash.sampler Я это сделал, для того чтобы Flash Platform не собирала образы с инициализации наших таймеров. Хотя это и не важно, но это послужит примером того, как не записывать в образы работу агентов обеспечивающих их сборку.

Теперь создадим обработчики событий наших таймеров:
Код AS3:
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);
}
Как вы наверное знаете каждому displayObject среда Flash определяет имя самостоятельно. Но чтобы точно удостовериться в том, что это наши спрайты я сделал свои пометки вида sprite_0, sprite_1, sprite_n ...

теперь функция сборщик образов
Код AS3:
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

Код AS3:
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);     
           }         
 
     }
}


Код AS3:
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);   
     } 
}

Код AS3:
private function catchSample (sample:Sample, actionsCount:int) :void
{
     // эта функция в контексте нашего кода вызывается в том слкучае, если образ (sample) не является объектом
     // NewObjectSample и DeleteObjectSample, в массиве stack таких образов хранятся внутренние события плеера 
     // (internal actions), но это тема для отдельной дискуссии поэтому оставим пока тело функции пустым    
}

Теперь как осталось только дописать два заключительных метода, завершающих работу таймеров
Код AS3:
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

Комментарии

Старый 29.11.2010 09:33 alexcon314 вне форума
alexcon314
Образ.. отлавливать образы.. сборщик образов.. чтобы Flash Platform не собирала образы.. функцию собирающую образы..
Не понял, что вы вкладываете в этот термин... это просто Sprite (DisplayObject)? Звучит как-то загадочно-заумно).
Старый 29.11.2010 13:28 inozemcev вне форума
inozemcev
 
Аватар для inozemcev
Нет это объект Sample и наследуемые от него NewObjectSample и DeleteObjectSample
Старый 01.12.2010 01:59 inozemcev вне форума
inozemcev
 
Аватар для inozemcev
Немного громоздко получилось. Суть в следующем:

Метод getSamples возвращает объект - массив с ключами. Каждый ключ это либо объект Sample, либо объект NewObjectSample либо DeleteObjectSample. NewObjectSample попадает в массив тогда когда flash platform фиксирует создание нового объекта, каждый такой объект она помечает id свойством. В NewObjectSample также есть ссылка на созданный объект.
Таким образом мы можем зафиксировать создание нового объекта.

В объекте DeleteObjectSample нет ссылки на объект (понятно ведь его уже не существует), но зато есть свойство id, по которому мы можем 'вспомнить' его, если заранее об этом побеспокоились и поместили его в свой массив с ключами.

В объекте sample нет ссылок на объекты, как правило в них есть только stack (стек вызовов) внутренних функций плеера (Таких как [reap], [render], [mark], [sweep], [mouse event] итд)
 

 


Часовой пояс GMT +4, время: 22:41.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.