Утечка памяти в Spark Combox - PullRequest
       29

Утечка памяти в Spark Combox

0 голосов
/ 12 февраля 2011

У меня есть простая, воспроизводимая утечка памяти, связанная с полем Spark Combo, однако я убежден, что это не то, что я делаю, а ошибка SDK.

// Application.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
    <s:layout>
        <s:VerticalLayout />
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            private var hasElement:Boolean;
            protected function toggleContainer():void
            {
                if (hasElement)
                {
                    button.setFocus();
                    comboBoxContainer.removeAllElements();
                    hasElement = false;
                } else {
                    var vew:ComboBoxView = new ComboBoxView();
                    comboBoxContainer.addElement(vew);
                    hasElement = true;
                }
            }
        ]]>
    </fx:Script>
    <s:Button id="button" label="Add container" click="toggleContainer()"  />
    <s:Group id="comboBoxContainer" />
</s:Application>


// ComboBoxView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         >
    <s:ComboBox />
</s:VGroup>

При компиляциипо сравнению с Flex 4.1 это создает утечку памяти, когда ComboBoxView никогда не GC'd - из-за давней ссылки на ComboBox.

Вот вывод из профилировщика: enter image description here

Шаги для воспроизведения:

  • Создать проект с Application.mxml и ComboBoxView.mxml
  • Скомпилировать проект с помощью Flex 4.1
  • Запустить Application.mxml с помощьюprofiler
  • Создание снимка памяти
  • Нажмите кнопку, чтобы добавить вид на сцену
  • Нажмите кнопку еще раз, чтобы снять вид со сцены
  • Запустите сборщик мусора
  • Создайте еще один снимок памяти
  • Просмотрите устаревшие объекты между двумя снимками памяти

Примечание - это не происходит, когда приложение компилируется сFlex Hero.

Кажется, что это ошибка, но я не могу поверить, что в ComboBox есть утечка памяти - наверняка это было бы исправлено до того, как 4.1 был отправлен?

Что я делаюздесь не так?Почему представление не является GC'd?

Обновление Я провел дальнейшее исследование этого и считаю, что проблема заключается в проблеме с компонентом RichEditableText, который использует ComboBoxSkin.Подробности здесь: Искры утечки памяти

Ответы [ 2 ]

1 голос
/ 07 июня 2011

http://www.iampj.com/search/label/combobox%20memory%20leak

У меня были аналогичные проблемы в flex 3

0 голосов
/ 12 февраля 2011

MXML иногда сложен, потому что вы никогда точно не знаете, что происходит за кулисами (если вы не используете атрибут -keep и look).

Но мне кажется, что вы никогда не обнуляете ссылку ComboBox.Удаление дочернего элемента контейнера - это не то же самое, что удаление этого экземпляра из памяти.Например, в компоненте «Календарь Flextras» мы нередко удаляем дни из отображения по мере изменения месяцев.В зависимости от месяца может отображаться от 28 до 31 дня.Но если у вас месяц с 31 днем ​​и вы переключаетесь на месяц с 30 днями, мы не аннулируем эти дополнительные дневные средства визуализации, мы просто кешируем их в массиве «unusedDays», а затем мы готовим их для следующегоВремя меняет месяц.

Классы ListBase работают аналогично, и я считаю, что Flex 4 даже имеет свойство с именем useVirtualLayout для управления тем, как эти вещи хранятся в памяти.

Я надеюсь, что это не было слишком длинным или самоубийственным объяснением, и я надеюсь, что оно имело смысл.

Я думаю, вам нужно что-то сделать, чтобы обнулить ComboBox.Первое, что я бы попробовал, это дать ComboBox идентификатор:

<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         >
    <s:ComboBox id="myComboBox" />
</s:VGroup>

Затем в своем коде ActionScript создайте экземпляр ComboBoxView (не локально для функции):

protected var vew:ComboBoxView = new ComboBoxView();

А затем разберитесь со сборкой мусора следующим образом:

        if (hasElement)
        {
            button.setFocus();
            comboBoxContainer.removeAllElements();
            comboBoxContainer.myComboBox = null;
            comboBoxContainer = null;
            hasElement = false;
        } else {
            var vew:ComboBoxView = new ComboBoxView();
            comboBoxContainer.addElement(vew);
            hasElement = true;
        }
    }

Я не проверял себя сам, и моя интуиция заключается в том, что не все эти шаги необходимы;но я подозреваю, что мой подход, вероятно, правильный.

...