Подводные камни Dictionary
Dictionary прекрасная штука, но его документация умалчивает о двух подводных камнях не знание о которых чревато утечками памяти или потерей данных
1. если в качестве ключа в словаре со слабыми ссылками использовать метод, то эта запись подлежит удалению сборщиком мусора вне зависимости от того есть другие ссылки на хозяина метода или нет.
(запись удаляется когда кажется что не должна)
package { import flash.display.Sprite; import flash.system.System; import flash.utils.Dictionary; import flash.utils.setTimeout; public class MemTest extends Sprite { private var d:Dictionary = new Dictionary(true); public function MemTest() { d[m] = 'test'; count(); //1 System.gc(); setTimeout(count, 1000); //0 } public function count():void { var n:uint=0, o:Object for (o in d){ n++; } trace(n); } public function m():void {} } }
дело в том что вместо метода передаётся ссылка на MethodClosure - специальный нативный скрытый тип, хранящий ссылку на хозяина оригинального метода и отвечающий за область видимости, но вот у хозяина на MethodClosure ссылки нет, отсюда и такое поведение Dictionary
2. если в словаре со слабыми ссылками в качестве значения присвоить тот самый объект который является ключом, то, если других ссылок на этот объект нету, пара ключ-значение удалению сборщиком мусора не подлежит.
(запись не удаляется когда кажется что должна)
package { import flash.display.Sprite; import flash.system.System; import flash.utils.Dictionary; import flash.utils.setTimeout; public class MemTest extends Sprite { private var d:Dictionary = new Dictionary(true); private var a:A; public function MemTest() { a = new A(); d[a] = a; count(); //1 a = null; System.gc(); setTimeout(count, 1000); //1 } public function count():void { var n:uint=0, o:Object for (o in d){ n++; } trace(n); } } } class A {}
Всего комментариев 15
Комментарии
04.09.2012 20:56 | |
04.09.2012 22:09 | |
проще сделать так:
dict = new Dictionary(); |
04.09.2012 23:50 | |
Цитата:
проще сделать так:
|
04.09.2012 23:56 | |
Ну да, можно просто создать новый, но я хотел минимизировать вызовы GC.
|
05.09.2012 00:12 | |
05.09.2012 02:07 | |
насколько я знаю delete не очищает память а удаляет ссылку, поэтому в любом случае сборщику мусора будет работа
но я не уверен какой из способов займёт меньше сил у GC, и, возможно я не прав, но мне кажется это не сильно существенным. в AS3 есть только два метода которые непосредственно очищают память BitmapData::dispose() и disposeXML() |
|
Обновил(-а) artcraft 05.09.2012 в 02:23
|
05.09.2012 18:13 | |
05.09.2012 20:33 | |
>> i.o.
отличный вариант только определение переменной р стоит вынести за пределы циклов, и задать ей тип Object >> wvxvw о да, это я погорячился обнулять локальную переменную, сейчас поправлю обе вещи которые я описал, багами не считаю, это просто не слишком очевидное поведение мягких ссылок которое может привести к неприятным последствиям |
|
Обновил(-а) artcraft 05.09.2012 в 20:48
|
Последние записи от artcraft
- Что такое entity framework (12.09.2012)
- Подводные камни Dictionary (04.09.2012)
- Волшебное превращение Object --> Class (04.09.2012)
- Инверсия контроля (14.04.2012)
- Loose coupling (10.01.2012)