Компонент не получает мусор - PullRequest
3 голосов
/ 18 октября 2010

Я только что заметил странное поведение при просмотре своего приложения во Flash Profiler.Когда я нажимаю кнопку в моем TitleWindow, тогда TitleWindow не получает мусор после его удаления.Я понятия не имею, почему это происходит.

Я создал небольшой пример приложения, поэтому вы можете попробовать его сами:

Main.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" pageTitle="Memory Leak (Spark)">

    <fx:Script>
        <![CDATA[
            protected function openWindowBtn_clickHandler():void
            {
                removeAllElements();
                addElement(new ExampleView());
            }
        ]]>
    </fx:Script>

    <s:controlBarContent>
        <s:Button label="Open Window" id="openWindowBtn" click="openWindowBtn_clickHandler()"/>
    </s:controlBarContent>
</s:Application>

ExampleView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%" title="Example View" close="closeHandler()">

    <fx:Script>
        <![CDATA[
            import mx.core.IVisualElementContainer;

            protected function closeHandler():void
            {
                var visualElementParent:IVisualElementContainer = parent as IVisualElementContainer;

                if (visualElementParent)
                    visualElementParent.removeElement(this);
                else
                    parent.removeChild(this);
            }
        ]]>
    </fx:Script>

    <s:layout>
        <s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
    </s:layout>

    <s:Button id="doSomethingBtn" label="Click me!"/>
</s:TitleWindow>

Когда вы нажимаете «Открыть окно» и закрываете ExampleView, не нажимая «Нажмите меня!»Кнопка в нем, затем GC включается и удаляет ExampleView.Тем не менее, когда вы нажимаете кнопку «Нажмите меня!»и закройте ExampleView впоследствии, ExampleView останется в памяти навсегда.

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

Ответы [ 3 ]

2 голосов
/ 18 октября 2010

Я могу ошибаться, но iirc EventListener, добавленные в MXML, всегда создаются с сильной ссылкой, что помешало бы кнопке быть GC-кодом.

Вы пытались добавить EventListener вручную, установив егобыть слабой ссылкой?Если вы посмотрите на список EventListeners в отладчике, вы должны увидеть что-то вроде WeakMethodClosure, если оно было добавлено со слабой ссылкой.

1 голос
/ 18 октября 2010

Одна вещь, которую вы, вероятно, забудете, это то, что сборщик мусора не собирает объекты, на которые нет ссылок, в тот момент, когда они теряют последнюю ссылку.Обычно сборщик мусора собирает свободные экземпляры только после того, как вы создадите какой-либо объект, но даже не очевидно, будет ли он делать это в этот момент.Вы можете прочитать больше об этом здесь:

О сборке мусора

Или взгляните на эту презентацию: Сборка мусора - Алекс Харуи


<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" pageTitle="Memory Leak (Spark)">

<fx:Script>
    <![CDATA[
        protected function openWindowBtn_clickHandler():void
        {
            removeAllElements();
            addElement(new ExampleView());
        }

        protected function button1_clickHandler(event:MouseEvent):void
        {
            var o:Object = new Object();
            System.gc();
        }

    ]]>
</fx:Script>

<s:controlBarContent>
    <s:Button label="Open Window" id="openWindowBtn" click="openWindowBtn_clickHandler()"/>
    <s:Button label="Force GC"  click="button1_clickHandler(event)"/>
</s:controlBarContent>
</s:Application>

Взгляните на это.Если вы нажмете кнопку «Force GC» пару раз, она соберет окно ExampleW.В реальном приложении, которое что-то делает, это происходит без необходимости вызывать System.gc () (на самом деле это не очень хорошая практика), но через некоторое время, так что вещи не просто исчезают, когда выс ними покончено, они исчезают, когда вы закончите, и Flash Player решает, что ему нужно очистить.

0 голосов
/ 02 июля 2015

Похоже, что ExampleView не получает сборщик мусора, потому что каким-то образом некоторый EventListener добавляется при нажатии "Click Me".Лучший способ избежать этого - 1. вручную добавить прослушиватель событий в событие createComplete. 2. удалить EventListener в closeHandler. 3. удалить кнопку из контейнера и установить для нее значение null

.

...