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

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 30.05.2013, 15:34
allex вне форума Посмотреть профиль Отправить личное сообщение для allex Найти все сообщения от allex
  № 1  
Ответить с цитированием
allex
[+3 05.12.12]

Регистрация: Mar 2012
Сообщений: 46
По умолчанию Утечка памяти

Доброго времени суток уважаемые гуру.У меня такая проблема - создаю постоянно объекты,и сразу их удаляю.Со временем падает fps а память сильно растет.Хотелось бы услышать Ваши советы.В прикреплении пример.Если нажать ё(~) ,то будет виден fps и память.Вот сам код создания объектов и удаление их.

Код AS3:
 
import components.*;
import flash.events.Event;
import flash.display.MovieClip;
 
var Component:Components=new Components(stage);
 
var arrOfElements:Array = [];
 
var i:int=0;
var j:int =0;
addEventListener(Event.ENTER_FRAME, stageEF);
 
function stageEF(e:Event){
	for(i=0; i<3; i++){
		var newmc:MovieClip =new mcAs();
		newmc.x=stage.stageWidth/2;
		newmc.y=300;
		newmc.scaleX=newmc.scaleY=2*(0.5-Math.random());
		newmc.scaleY=Math.abs(newmc.scaleY); 
		addChild(newmc);
		arrOfElements.push(newmc);
	}
 
for (j = 0; j< arrOfElements.length;j++ )
{
	trace (arrOfElements.length)
	if  (arrOfElements[j] == arrOfElements[j].totalFrames)
	removeChild(arrOfElements[j]);
	arrOfElements[j] = null;
	arrOfElements.splice(j,1);
}
 
}
Вложения
Тип файла: rar primer.rar (14.9 Кб, 21 просмотров)

Старый 30.05.2013, 16:14
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 2  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Удаляющий отработанные объекты код написан не верно:
Код:
if  (arrOfElements[j].currentFrame == arrOfElements[j].totalFrames){
	removeChild(arrOfElements[j]);
	arrOfElements[j] = null; // Не обязательно
	arrOfElements.splice(j,1);
	j--;
}
Да и сам цикл вроде-бы будет не всегда удалять сразу, из-за проскакивания через удалённые объекты. Нужно добавить: j-- при удалений в одной итераций

Зачем вам хранить спрайты в отдельном массиве? Их можно получать из дисплей контейнера, в котором они лежат.
__________________
Дети не должны знать о своих родителях

Старый 30.05.2013, 17:51
Final Hope вне форума Посмотреть профиль Найти все сообщения от Final Hope
  № 3  
Ответить с цитированием
Final Hope
Banned
[+5 04.06.13]
[+1 08.06.13]

Регистрация: May 2013
Сообщений: 52
Я где-то слышал, что лучше не создавать каждый раз новые объекты, а хранить старые в так называемом пуле (бассейне). Например, имеется пул. В этот пул сохраняется необходимое число объектов. А потом, когда нужно, из пула берутся объекты и добавляются на сцену. А когда на сцене объекты больше не нужны, то они обратно прячутся в пул. Тем самым память не трещит по швам. Если я ничего не путаю, то выглядит это примерно так:
Код AS3:
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
 
var particlesOnPool:Vector.<Sprite> = new <Sprite>[];
var particlesOnScene:Vector.<Sprite> = new <Sprite>[];
const COUNT_ON_TIME:int = 3;
const FLOOR:int = 300;
 
var traceTextField:TextField = new TextField();
traceTextField.width = 300;
this.addChild(traceTextField);
 
stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
//----------------------------------------------------------------
//  Methods
//----------------------------------------------------------------
function addNewParticle():void
{
	var particle:Sprite = new Sprite();
	particle.graphics.beginFill(0x000000);
	particle.graphics.drawCircle(0, 0, 2);
	particlesOnPool.push(particle);
}
//----------------------------------------------------------------
//  Event Handlers
//----------------------------------------------------------------
function stage_enterFrameHandler(event:Event):void
{
	var particle:Sprite;
	for (var i:int = 0; i < COUNT_ON_TIME; i++)
	{
		if (particlesOnPool.length != 0)
		{
			particle = particlesOnPool.pop();
			particle.x = 200 + Math.random() * 50;
			particle.y = 200 + Math.random() * 50;
			this.addChild(particle);
			particlesOnScene.push(particle);
		}
		else
		{
			addNewParticle();
			i--;
		}
	}
	var particlesOnSceneLength:int = particlesOnScene.length;
	for (i = 0; i < particlesOnSceneLength; i++)
	{
		particle = particlesOnScene[i];
		particle.y += 3;
		if (particle.y >= FLOOR)
		{
			this.removeChild(particle);
			particlesOnScene.splice(i, 1);
			particlesOnPool.push(particle);
			particlesOnSceneLength = particlesOnScene.length;
			i--;
		}
	}
	var particlesOnPoolLength:int = particlesOnPool.length;
 
	traceTextField.text = "На сцене: " + particlesOnSceneLength.toString() +
	" | В запасе: " + particlesOnPoolLength.toString() + 
	" | Всего партиклов в памяти: " + (particlesOnSceneLength + particlesOnPoolLength).toString();
}
Untitled-4.swf   (1.9 Кб)
Вложения
Тип файла: swf Untitled-4.swf (1.9 Кб, 50 просмотров)


Последний раз редактировалось Final Hope; 30.05.2013 в 18:03.
Старый 30.05.2013, 18:09
allex вне форума Посмотреть профиль Отправить личное сообщение для allex Найти все сообщения от allex
  № 4  
Ответить с цитированием
allex
[+3 05.12.12]

Регистрация: Mar 2012
Сообщений: 46
Цитата:
Сообщение от Tails Посмотреть сообщение
Удаляющий отработанные объекты код написан не верно:
Код:
if  (arrOfElements[j].currentFrame == arrOfElements[j].totalFrames){
	removeChild(arrOfElements[j]);
	arrOfElements[j] = null; // Не обязательно
	arrOfElements.splice(j,1);
	j--;
}
Да и сам цикл вроде-бы будет не всегда удалять сразу, из-за проскакивания через удалённые объекты. Нужно добавить: j-- при удалений в одной итераций

Зачем вам хранить спрайты в отдельном массиве? Их можно получать из дисплей контейнера, в котором они лежат.

спасибо за ответ,как то с j-- не догадался. А вот почему обнулять не обязательно?И если происходит ремув объектов,разве можно брать из дисплея контейнера?

Старый 30.05.2013, 18:18
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 5  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Если есть возможность, нужно делать с пулом, как посоветовали выше.

Обнулять не обязательно, потому-что вы следующей строкою и так удаляете этот итем из массива.
Если делать без массива и брать из дисплей контейнера, то к удалённым объектам обратиться разумеется будет нельзя. Но вы в вашем коде к ним и не обращаетесь.
__________________
Дети не должны знать о своих родителях

Создать новую тему Ответ Часовой пояс GMT +4, время: 11:46.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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