如何发布ListView的源内存?

问题描述 投票:0回答:1

我希望在引用保存大内存的情况下立即释放ListView的ItemsSource引用。

但是,即使我的代码中没有任何引用,GC也不会发布引用。例如,我期望使用下面的“免费”按钮释放byte[]

SimpleListView.xaml

<Window x:Class="PlayWPF.SimpleListView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SimpleListView" Height="450" Width="800">
  <DockPanel LastChildFill="True">
    <ListView Name="LvTest" Width="500" DockPanel.Dock="Left"/>
    <Button Content="Alloc" Click="AllocClick" Height="200" DockPanel.Dock="Top"/>
    <Button Content="Free" Click="FreeClick"/>
  </DockPanel>
</Window>

SimpleListView.xaml.cs

public partial class SimpleListView : Window {
  public SimpleListView() {
    InitializeComponent();
  }

  private void AllocClick(object sender, RoutedEventArgs e) {
    var list = new List<byte[]>();
    list.Add(new byte[100000000]);
    LvTest.ItemsSource = list;
  }

  private void FreeClick(object sender, RoutedEventArgs e) {
    LvTest.ItemsSource = null;
    //LvTest.ItemsSource = new List<int>();
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
    GC.WaitForPendingFinalizers();
  }
}

点击“免费”按钮没有任何区别,使用new List<int>(),它会在第二次试用时发布参考。即使我关闭窗口,引用也会保持活动状态。

我怎样才能理想地释放它?

编辑:它已被标记可能重复Why Large Object Heap and why do we care?,但改变.NET 4.7.1上的LargeObjectHeapCompactionMode没有任何影响。

我找到了解决方案,使用ObservableCollection而不是简单的List来回答原始问题,但我不知道这是如何以及为什么这会产生影响。为了留下好奇心,我把这个问题保持开放。

c# wpf memory-leaks .net-4.5
1个回答
0
投票

在当前删除的blog post上描述了它。

TextBlock控件具有绑定到对象(myGrid)的对象,该对象具有对TextBlock(它是myGrid子节点之一)的引用。 请注意,这种类型的DataBinding泄漏对于特定方案(而不是所有DataBinding方案)是唯一的,如kb文章中所述。 Path中的属性不是DependencyProperty,也不是实现INotifyPropertyChanged的类,此外还必须存在一系列强烈崇敬。

根据这个,我误用数据绑定,正确的免费代码段如下。

BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);
© www.soinside.com 2019 - 2024. All rights reserved.