Пример утечки памяти AS3 - PullRequest
       5

Пример утечки памяти AS3

9 голосов
/ 09 апреля 2010

Может ли кто-нибудь опубликовать пример кода as3 (в частности, прослушиватель событий), который будет простым примером чего-то, что может привести к утечке памяти ... также надеюсь, вы могли бы опубликовать решение указанной проблемы?

Вопрос в том, что является простым примером утечки памяти в слушателе событий AS3 и как вы можете ее решить?

Ответы [ 3 ]

7 голосов
/ 10 апреля 2010
public class MySprite extends Sprite {

    public function MySprite() {
        if(stage) {
            init();
        } else {
            addEventListener(Event.ADDED_TO_STAGE,init);
        }
    } 

    private function init(e:Event = null):void {
        stage.addEventListener(Event.RESIZE,handleStageResize);
    }

    private function handleStageResize(e:Event):void {
        //  do some processing here.
    }

}

Где-то еще:

var mySprite:MySprite = new MySprite();
someHolder.addChild(mySprite);

Теперь, если в какой-то более поздний момент вы удалите mySprite, он все еще будет зависать в памяти, потому что он добавил себя (или ссылку на себя) на этап в методе init ().

В этом сценарии лучшим способом избежать этого может быть удаление слушателя, добавленного на сцену, когда mySprite удаляется из списка отображения.

    private function init(e:Event = null):void {
        addEventListener(Event.REMOVED_FROM_STAGE,cleanUp);
        stage.addEventListener(Event.RESIZE,handleStageResize);

    }

    private function cleanUp(e:Event):void {
       stage.removeEventListener(Event.RESIZE,handleStageResize); 
    }

Я уверен, что другие люди скажут вам использовать слабые ссылки при добавлении слушателя на сцену, но вы все равно должны удалить своих слушателей. Если вы этого не сделаете, то, когда вы удалите mySprite из списка отображения и не будете иметь никаких других ссылок на него, вы будете иметь право на GC и в конечном итоге будут стерты из памяти. Но пока это не произойдет, код в handleStageResize () продолжит выполняться.

4 голосов
/ 29 мая 2011

Я просто продолжу @ ответ Хуана - GC нужно рассматривать с нуля как критически важный аспект разработки приложений. Если вы создаете объект, вы должны знать каждую ссылку на него, удалять каждую ссылку и обнулять ее, чтобы правильно пометить @. Если вы ссылаетесь на этот объект в массиве, это считается, если вы ссылаетесь на него в слушателе, это считается, если вы ссылаетесь на него через локальную переменную, это тоже считается (хотя только в течение жизни функции), если его просто в список отображения, который определенно считается, и так далее.

Я дошел до того, что написал свои операторы удаления прослушивателя, прежде чем добавить их , просто чтобы убедиться, .

Я почти всегда напишу открытый метод destroy () для любого объекта, который будет обрабатывать иерархии внутренних объектов (родительские вызовы destroy для child, которые, в свою очередь, вызывают destroy для любых дочерних объектов и т. Д. И т. Д.). Простое удаление / обнуление родителя без того, чтобы сделать это для каждого ребенка, - плохое управление GC.

И если у вас есть какие-либо опасения, что возникла утечка памяти, отследите System.totalMemory, чтобы убедиться:

var mem:String = Number( System.totalMemory / 1024 / 1024 ).toFixed( 2 ) + ‘Mb’;
trace( mem ); // eg traces “24.94Mb”

В основном - просто будьте методичны в этом - это не ракетостроение, но вы должны быть осторожны.

Приветствия -

@ и даже если вы это сделаете, Flash решает, когда на самом деле делать зачистку. Лучшее, что мы можем сделать, это убедиться, что объект правильно помечен и верит , что с ним будет эффективно работать.

0 голосов
/ 29 мая 2011

Я не собираюсь публиковать пример этого, но объясню немного. Здесь вы описываете 2 ситуации.

  1. утечки памяти
  2. переполнение процессора

AS3 по-разному обрабатывает операции с памятью и процессором.

Утечки памяти происходят, когда много объектов создано и уничтожено. Объекты теряют память, когда у них есть ссылки, и объект уничтожается без уничтожения ссылок, поэтому блок памяти неиспользованного объекта = утечка.

Переполнение процессора происходит, когда у вас много методов, ссылающихся друг на друга без «закрытия цикла».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...