【问题标题】:Silverlight DataTemplate Memory LeakSilverlight DataTemplate 内存泄漏
【发布时间】:2011-05-08 12:34:18
【问题描述】:

任何人对我有一个解释,为什么下面的样式应用于绑定到 2000 个项目集合的 Silverlight 列表框在滚动列表时会像疯了一样泄漏内存?内存使用量很快达到数百兆。

仅当我将 ItemsControl 留在其中时才会发生泄漏。否则内存消耗将保持不变。如果有问题的 ItemsControl 绑定到的“Tags”属性(类型:string[])从它的 getter 返回一个静态只读数组,也不会发生泄漏。

这是“标签”属性 getter 的实现,我尝试在循环中调用列表项的 getter 也会泄漏,但事实并非如此。我们谈论的是每个集合项目 1-5 个标签 = 最多 10000 个字符串。似乎只有在 ItemsControl 绑定到非静态集合时才会发生泄漏。

运行时版本是 4.0.60310.0,AFAIK 高于应该修复 DataTemplate MemoryLeak 的版本。

<Style x:Key="DocumentHybridListBox" TargetType="ListBox">
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="3"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling"  Orientation="Vertical" Margin="1, 3, 1, 3" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Image Grid.Column="0" Style="{StaticResource DocumentList_Hybrid_Image}">
                        <Image.Source>
                            <BitmapImage Behaviors:BindableBitmapImageSource.Source="{Binding PreviewPicture}"></BitmapImage>
                        </Image.Source>
                    </Image>
                    <Grid Grid.Column="1" Margin="6, 0, 0, 0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <TextBlock Grid.Row="0" Text="{Binding Summary}" FontWeight="Bold" TextTrimming="WordEllipsis"></TextBlock>
                        <TextBlock Grid.Row="2" Text="{Binding DateSummary}" FontSize="11" TextTrimming="WordEllipsis"></TextBlock>

                        <!--- Problem starts here -->
                        <ItemsControl Grid.Row="1" ItemsSource="{Binding Tags}" Margin="0, 3, 0, 3">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"></StackPanel>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding}" Style="{StaticResource TagButton}"
                                        Command="{Binding DataContext.TagDrillDownCmd, ElementName=Self}"
                                        CommandParameter="{Binding}"
                                        ToolTipService.ToolTip="{Binding Converter={StaticResource tagTooltipConverter}}"></Button>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Grid>
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

标签属性:

private string[] _tags = null;
static readonly string[] constTags = new [] { "foo", "bar "};

public string[] Tags
{
    get
    {
        //return constTags; // this won't leak if bound to ItemsControl
        if (_tags == null)
        {
            // initialize
            if (Document.Tags != null && Document.Tags.Length != 0)
            {
                // initialize
                _tags = Document.Tags.Select(t => Decrypt2String(t,
                    ServiceLocator.Get<IKeyContainer>().DerivedContentEncryptionKey)).ToArray();
            }
        }

        return _tags;
    }

    set
    {
        _tags = value;
        OnPropertyChanged(()=>Tags);
    }
}

【问题讨论】:

    标签: silverlight memory-leaks


    【解决方案1】:

    Silverlight 数据模板中存在与内存泄漏相关的已知问题。它已经存在了相当长的一段时间。查看this链接

    【讨论】:

    • 我知道那个帖子。但至少与 DataTemplate 相关的泄漏应该在不久前用补丁修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多