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

发布于 11-13 05:09 字数 1873 浏览 3 评论 0原文

我有一个关于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

戒ㄋ2024-11-20 05:09:32

我还没有机会查看 Flex 4.5 DataGrid 代码,但我想他们正在使用 项目渲染器的对象池

DataGrid 的核心在于速度,而花费最多时间的通常是项目渲染器(尤其是实例化)。为了保持 DataGrid 的快速运行,它们不会立即“销毁”项目渲染器。它将保留它们 x 时间;或者对于某些对象池算法,永远不要释放它们。将它们保留在内存中会更容易,因为它们一开始就不会很大并且具有更快的动态 DataGrid。

事实上,我在谷歌上进行了快速搜索,我是对的

所有这些 DataGrid IFactory 皮肤
零件需要是
IVisualElements。在很多情况下他们是
只是 GraphicElements,例如 Rects 或
线条,可以相当渲染
高效,因为 Flex 运行时的
“显示对象共享”支持使用
单个 DisplayObject 来渲染所有
其中。就像项目渲染器一样,
这些视觉元素是内部的
集中回收,避免成本
创建并添加它们
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:

All of these DataGrid IFactory skin
parts are required to be
IVisualElements. In many cases they're
just GraphicElements like Rects or
Lines, which can be renderered quite
efficiently because the Flex runtime's
"display object sharing" support uses
a single DisplayObject to render all
of them. Just like item renderers,
these visual elements are internally
pooled and recycled, to avoid the cost
creating and adding them when the
DataGrid is scrolled.

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.

清晨说晚安2024-11-20 05:09:32

我相信您问题的答案是“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”,所以也许这不是您问题的答案。

I beleive the answer to your question is the "useVirtualLayout" property.

Instead of creating an item renderer for each child, you can configure the container to use a virtual layout. With virtual layout, the container reuses item renderers so that > it only creates item renderers for the currently visible children of the container. As a child is moved off the screen, possible by scrolling the container, a new child being scrolled onto the screen can reuse its item renderer.

To configure a container to use virtual layout, set the useVirtualLayout property to true for the layout associated with the container. Only DataGroup or SkinnableDataContainer with layout set to VerticalLayout, HorizontalLayout, or TileLayout supports virtual layout. Layout subclasses that do not support virtualization must prevent changing this prope"

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

Edit: Just found out that DataGrids only support VirtualLayouts, as it uses the custom "GridLayout". So maybe this isn't the answer to your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文