Использование памяти Spark Datagrid с динамическими столбцами - PullRequest
3 голосов
/ 04 июня 2011

У меня есть вопрос о Spark DataGrid и о том, как он работает с точки зрения сбора мусора.Я обнаружил, что если я динамически добавляю и удаляю столбцы из DataGrid во время выполнения, GridColumns и ItemRenderers никогда не освобождаются из памяти.

Например, если у меня есть список из 10 элементов, и я создаю10 столбцов, будет 100 ItemRenderers и 10 GridColumns.Если я удаляю все столбцы, они все еще там.

Если я добавлю 5 столбцов назад, это не создаст экземпляров больше GridColumns или ItemRenderers - в памяти все еще остается 100 полных средств визуализации и 10 столбцов.

Этого не происходит с MX DataGrid.По мере удаления столбцов ItemRenderers и DataGridColumns освобождаются из памяти, а когда я смотрю на профилировщик, я вижу 0 ItemRenderers и 1 DataGridColumn.

Кто-нибудь знает, что здесь происходит?Или я просто что-то упустил?

Вот код, который я использовал для проверки Spark DataGrid:

<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" minWidth="955" minHeight="600">
    <fx:Declarations>
        <s:ArrayList id="dp">
            <fx:Object label="label 1"/>
            <fx:Object label="label 2"/>
            <fx:Object label="label 3"/>
            <fx:Object label="label 4"/>
            <fx:Object label="label 5"/>
            <fx:Object label="label 6"/>
            <fx:Object label="label 7"/>
            <fx:Object label="label 8"/>
            <fx:Object label="label 9"/>
            <fx:Object label="label 10"/>
        </s:ArrayList>
        <s:ArrayList id="columns">
            <s:GridColumn dataField="label"/>
        </s:ArrayList>
    </fx:Declarations>
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <s:DataGrid dataProvider="{dp}" columns="{columns}" width="100%" height="100%"/>

    <s:HGroup>
        <s:Button label="Add Column" click="columns.addItem(new GridColumn('label'))"/>
        <s:Button label="Remove Column" click="if( columns.length > 0 ) columns.removeItemAt(0)"/>
    </s:HGroup>
</s:Application>

Ответы [ 2 ]

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

У меня еще не было возможности просмотреть код Flex 4.5 DataGrid, но я думаю, они используют пул объектов для средств визуализации элементов.

DataGrid - это все о скорости, и то, что обычно занимает больше всего времени, обычно это средства визуализации элементов (особенно экземпляры). Чтобы сохранить DataGrid быстро, они не «уничтожают» средства визуализации элементов сразу. Он будет держаться на них х раз; или для некоторых алгоритмов объединения объектов никогда не выпускайте их. Проще просто хранить их в памяти, поскольку они не должны быть огромными и иметь более быструю динамическую DataGrid.

На самом деле, я сделал быстрый поиск в Google и Я был прав :

Все эти скин DataGrid IFactory части должны быть IVisualElements. Во многих случаях они просто GraphicElements, такие как Rects или Линии, которые можно рендерить довольно эффективно, потому что среда выполнения Flex поддержка "совместного использования экранных объектов" использует один DisplayObject для отображения всех из них. Так же, как средства визуализации предметов, эти визуальные элементы внутренне объединены и переработаны, чтобы избежать затрат создавая и добавляя их, когда DataGrid прокручивается.

Кажется, что средства визуализации элементов объединяются не только внутри каждой DataGrid, но и для всех DataGrids. Очень хорошая практика, я должен сказать. И поверьте мне, это очень полезно для производительности Flex в DataGrids.

0 голосов
/ 06 июня 2011

Я полагаю, что ответом на ваш вопрос является свойство useVirtualLayout.

Вместо создания средства визуализации элементов для каждого дочернего элемента вы можете настроить контейнер на использование виртуального макета.В виртуальном макете контейнер повторно использует средства визуализации элементов, так что> он создает средства визуализации только для видимых в данный момент дочерних элементов контейнера.Поскольку дочерний элемент перемещается за пределы экрана, возможно путем прокрутки контейнера, новый дочерний элемент, прокручиваемый на экране, может повторно использовать средство визуализации элементов.

Чтобы настроить контейнер для использования виртуального макета, установите для свойства useVirtualLayout значение true.для макета, связанного с контейнером.Только DataGroup или SkinnableDataContainer с макетом, установленным в VerticalLayout, HorizontalLayout или TileLayout, поддерживают виртуальный макет.Подклассы макета, которые не поддерживают виртуализацию, должны препятствовать изменению этого свойства "

Источник: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/layouts/supportClasses/LayoutBase.html#useVirtualLayout

Редактировать : только что выяснилось, что DataGrids поддерживают только VirtualLayouts,так как он использует пользовательский «GridLayout». Так что, возможно, это не ответ на ваш вопрос.

...