Spark Datagrid 动态列的内存使用情况
我有一个关于 Spark DataGrid 及其在垃圾处理方面如何工作的问题 收藏。我发现如果我动态添加和删除列 在运行时从 DataGrid 中,GridColumns 和 ItemRenderers 永远不会被释放 从记忆中。
例如,如果我有一个包含 10 个项目的列表,并且我创建了 10 列,那么将会有 是 100 个 ItemRenderer 和 10 个 GridColumn。如果我删除所有列,它们 仍然在那里。
如果我重新添加 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>
I have a question about the Spark DataGrid and how it works in terms of garbage
collection. What I'm finding is that if I dynamically add and remove columns
from the DataGrid at runtime, the GridColumns and ItemRenderers never get freed
from memory.
For instance, if I have a list with 10 items and I create 10 columns, there will
be 100 ItemRenderers and 10 GridColumns. If I remove all of the columns, they
are still there.
If I add 5 columns back, it does not appear to instantiate more GridColumns or
ItemRenderers - there are still 100 total renderers and 10 columns in memory.
This doesn't happen with the MX DataGrid. As the columns are removed the
ItemRenderers and and DataGridColumns get freed from memory, when I look at the
profiler afterwards, I see 0 ItemRenderers and 1 DataGridColumn.
Does anybody have any idea about what would be going on here? Or am I just
missing something?
Here is the code that I used to test the 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
我相信您问题的答案是“useVirtualLayout”属性。
您可以将容器配置为使用虚拟布局,而不是为每个子项创建项目渲染器。通过虚拟布局,容器重用项目渲染器,以便 >它仅为容器当前可见的子项创建项目渲染器。当子项移出屏幕时(可以通过滚动容器),滚动到屏幕上的新子项可以重用其项目渲染器。
要将容器配置为使用虚拟布局,请将与容器关联的布局的 useVirtualLayout 属性设置为 true。仅布局设置为 VerticalLayout、HorizontalLayout 或 TileLayout 的 DataGroup 或 SkinnableDataContainer 支持虚拟布局。不支持虚拟化的布局子类必须防止更改此属性”
编辑:刚刚发现DataGrids仅支持VirtualLayouts,因为它使用自定义的“GridLayout”,所以也许这不是您问题的答案。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我还没有机会查看 Flex 4.5 DataGrid 代码,但我想他们正在使用 项目渲染器的对象池。
DataGrid 的核心在于速度,而花费最多时间的通常是项目渲染器(尤其是实例化)。为了保持 DataGrid 的快速运行,它们不会立即“销毁”项目渲染器。它将保留它们 x 时间;或者对于某些对象池算法,永远不要释放它们。将它们保留在内存中会更容易,因为它们一开始就不会很大并且具有更快的动态 DataGrid。
事实上,我在谷歌上进行了快速搜索,我是对的:
似乎项目渲染器不仅在每个 DataGrid 中汇集,而且针对所有 DataGrid。我不得不说非常好的做法。相信我,这对于 DataGrid 上的 Flex 性能非常有益。
I haven't had a chance to look over the Flex 4.5 DataGrid code yet, but I would imagine they're using object pooling for the item renderers.
The DataGrid is all about speed, and what takes the most amount of time is normally the item renderers (especially instantiation). To keep the DataGrid fast, they don't 'destroy' the item renderers right away. It will hold onto them for x amount of time; or for some object pooling algorithms, never release them. It's easier to just keep them in memory since they're not suppose to be huge in the first place and have a quicker dynamic DataGrid.
Actually, I did a quick google search and I was right:
It seems that item renderers are not only pooled within each DataGrid, but for all DataGrids. Very good practice I have to say. And trust me, this is very beneficial for Flex performance on DataGrids.