2011-06-04 4 views
3

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

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

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

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

Есть ли у кого-нибудь идеи о том, что здесь происходит? Или я просто что-то не хватает?

Вот код, который я использовал для тестирования Спарк 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> 
+0

«Если у меня есть список из 10 элементов 10 элементов, и я создаю 10 столбцов, будет 100 ItemRenderers», это верно, только если ваш DataGrid отображает 10 строк. вы DataGrid отображает 5 строк, тогда у вас есть 50 itemRenderers. [Примечание: я не уверен, что Spark DataGrid создает все co lumns сразу, как MX DataGrid; если это не так, у вас может быть меньше визуализаторов; на основе количества отображаемых столбцов) – JeffryHouser

+0

+1 для обеспечения полного, запускаемого образца. – JeffryHouser

ответ

1

у меня не было возможности посмотреть по коду DataGrid Flex 4.5, но я предположил бы, что они используют object pooling для рендеринга элемента.

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

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

Все эти DataGrid IFactory кожи части обязаны быть IVisualElements. Во многих случаях они просто GraphicElements как прямоугольники или линий, которые могут быть весьма отображенный эффективны, потому что «обменом экранного объекта» среды выполнения Flex в поддержке использует один DisplayObject, чтобы сделать все из них. Подобно визуализаторам элементов, эти визуальные элементы являются внутренними объединены и переработаны, чтобы избежать стоимости , создавая и добавляя их, когда прокручивается DataGrid .

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

0

Я верю, что ответ на ваш вопрос - это свойство useVirtualLayout.

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

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

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

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

Смежные вопросы