PDA

Просмотр полной версии : BitmapData & memory leaks


Ромастый
19.07.2007, 19:54
Случайно натолкнулся на такую вещь.
import flash.display.BitmapData;
var bm:BitmapData;
function createBitmap() {
bm = new BitmapData(200, 200, false, 0xFF000000);
}
onEnterFrame = createBitmap;
Тут все ок.

import flash.display.BitmapData;
function createBitmap() {
var bm:BitmapData = new BitmapData(1000, 1000, false, 0xFF000000);
}
onEnterFrame = createBitmap;
Во втором варианте наблюдаются некислая утечка памяти, которая периодически очищается коллектором. Фактически мы наблюдаем механизм очистки по меткам, но интересует другой вопрос - кто виноват и что делать, а точнее - если где-то создаются неявные или перекрестные ссылки на созданные экземпляры BitmapData, так что их приходится удалять по меткам, то почему этого не возникает в первом варианте? :confused:

Ромастый
19.07.2007, 20:02
Немного перефразирую вопрос. В первом случае как раз все понятно: в момент присваивания переменной bm нового объекта срабатывает механизм garbage collector'a очистки по ссылкам.

Но вот что происходит во втором случае, заставило меня ломать голову... Где, и каким макаром, остаются ссылки на созданные объекты, раз их приходится удалять по меткам???

Kikasso
19.07.2007, 20:48
Во втором случае ссылок не остается, но битмапа где-то крепко сидит, если ее надо не delete а dispose..

etc
19.07.2007, 21:02
В первом случае ты замещаешь старый битмап, а во втором постоянно создаешь новый битмап. Флеш плеер ставит некую отметку необходимого количества и переодически очищает память при превышении данной отметки (если, конечно, есть, что удалять).

Ромастый
20.07.2007, 13:39
Во втором случае ссылок не остается, но битмапа где-то крепко сидит, если ее надо не delete а dispose..
С dispose никаких вопросов, так как метод очищает память, занятую под объект битмапдаты, а именно удаляет массив пикселов и очищает каналы, но сам при этом экземпляр не удаляет.

delete удаляет ссылку на экземпляр. Если существуют другие ссылки - объект не удаляется. Собственно это мы и видим во втором примере. Если написать
var bm:BitmapData = new BitmapData(1000, 1000, false, 0xFF000000);
delete bm;
Утечка никуда не исчезает, и это значит, что действительно где-то есть еще ссылки. Вопрос - почему эти ссылки не возникают (или сразу удаляются) в варианте первом...

В первом случае ты замещаешь старый битмап, а во втором постоянно создаешь новый битмап. Флеш плеер ставит некую отметку необходимого количества и переодически очищает память при превышении данной отметки (если, конечно, есть, что удалять).

Собственно, это и так ясно из первого поста. Вопрос чуть выше...
И вопрос второй: если при замещении срабатывает механизм очистки по ссылкам, то почему он не срабатывает при выходе из функции createBitmap()?

Ромастый
20.07.2007, 13:49
А дальше, как говорила одна маленькая девочка из Зазеркалья - "Становится все страньше и страньше...."

Подобная хрень (назвать иначе язык не поворачивается) наблюдается в среде Flash8, но отсутствует во Flash9 (в том числе в альфе). Там никаких утечек.
Далее еще интереснее. В swf'ке, cкомпиленной восьмеркой, и запущенной в независимом плеере и в браузере утечка наблюдается.
А в скомпиленной из девятки под AS2, в ТОМ ЖЕ САМОМ плеере (9.0.45.0) никаких утечек. Ни в браузере, ни в независимом.

Делаем вывод - баг восьмерки. Граблю запомнить и не наступать.

etc
20.07.2007, 14:12
А я бы не наступил никогда :D
Ибо у меня битмапы по нормальным, не локальным ссылкам и убиваются, когда нужно :)
Судя по всему проблема именно с локальными ссылками.

iNils
20.07.2007, 14:34
http://www.gskinner.com/blog/archives/2005/10/major_flash_pla.html

Ромастый
20.07.2007, 14:57
iNils, сэнкс. Грабля редко бывает девственной - получив ручкой по башке проверь на наличие вмятин))

__etc, обычно так и делаю, поэтому столкнулся случайно.
Правильно ли я понял, что метка, которую флэш ставит на переменную внутри функции, для того, чтобы коллектор смог удалить объект из памяти, является одновременно "якорем", не позволяющим удалить объект сразу после выхода из функции?
Змея, кусающая себя за хвост?

Ромастый
20.07.2007, 15:00
И вдогонку, чтоб не создавать новой темы.
Существуют ли какие-то утилиты, позволяющие мониторить процессы внутри флэшплеера, с отображением, сколько памяти жрет тот или иной процесс или объект?

etc
20.07.2007, 15:11
i__etc, обычно так и делаю, поэтому столкнулся случайно.
Правильно ли я понял, что метка, которую флэш ставит на переменную внутри функции, для того, чтобы коллектор смог удалить объект из памяти, является одновременно "якорем", не позволяющим удалить объект сразу после выхода из функции?
Змея, кусающая себя за хвост?
Я не знаю, я не ковырялся во флеш-плеере.

Утил нет. В AS3 только общий объем пожираемой памяти можно узнать.

WindWalker
20.07.2007, 15:38
function setHandler() {
var s = "Hello";
btn.onPress = function() {
trace (s);
}
}

Локальная переменная s "выживет" после завершения setHandler();
И что-то меня терзают подозрения, что локальные переменные в Flash вообще не убиваются при окончании функции, просто с небольшими переменными это менее заметно, чем с бимапами.

Надо будет провести эксперимент с большими строками или массивами...