使用动态列的Spark Datagrid内存使用情况

时间:2011-06-04 14:51:22

标签: flex memory datagrid itemrenderer flex-spark

我有一个关于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 个答案:

答案 0 :(得分:1)

我还没有机会查看Flex 4.5 DataGrid代码,但我想他们会使用object pooling作为项目渲染器。

DataGrid与速度有关,花费最多时间的是项目渲染器(尤其是实例化)。为了使DataGrid保持快速,它们不会立即“破坏”项目渲染器。它会持续x个时间;或者对于某些对象池算法,永远不要释放它们。将它们保存在内存中更容易,因为它们首先并不是巨大的,并且具有更快的动态DataGrid。

实际上,我做了一个快速的谷歌搜索和I was right

  

所有这些DataGrid IFactory皮肤   零件必须是   IVisualElements。在许多情况下,他们是   只是像Rects或的GraphicElements   线条,可以很好地渲染   因为Flex运行时有效   “显示对象共享”支持使用   一个DisplayObject来渲染所有   他们就像物品渲染器一样   这些视觉元素在内部   汇集和回收,以避免成本   在创建和添加它们时   DataGrid已滚动。

似乎项目渲染器不仅汇集在每个DataGrid中,而且汇集在所有DataGrids中。我不得不说非常好的做法。相信我,这对DataGrids上的Flex性能非常有益。

答案 1 :(得分:0)

我相信你的问题的答案是“useVirtualLayout”属性。

  

您可以将容器配置为使用虚拟布局,而不是为每个子项创建项呈示器。使用虚拟布局,容器重用项目渲染器,以便>它只为容器的当前可见子项创建项呈示器。当孩子离开屏幕时,可以通过滚动容器,滚动到屏幕上的新孩子可以重复使用其项目渲染器。

     

要将容器配置为使用虚拟布局,请将与容器关联的布局的useVirtualLayout属性设置为true。只有布局设置为VerticalLayout,Horizo​​ntalLayout或TileLayout的DataGroup或SkinnableDataContainer支持虚拟布局。不支持虚拟化的布局子类必须防止更改此问题“

来源:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/layouts/supportClasses/LayoutBase.html#useVirtualLayout

编辑:刚发现DataGrids仅支持VirtualLayouts,因为它使用自定义“GridLayout”。所以这可能不是你问题的答案。