我有一个关于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>
答案 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,HorizontalLayout或TileLayout的DataGroup或SkinnableDataContainer支持虚拟布局。不支持虚拟化的布局子类必须防止更改此问题“
编辑:刚发现DataGrids仅支持VirtualLayouts,因为它使用自定义“GridLayout”。所以这可能不是你问题的答案。