如何释放ListView的源内存?
How can I release ListView's source memory?
我想立即释放 ListView 的 ItemsSource 引用,以防引用占用大量内存。
但是即使我的代码中没有任何引用,GC 也不会释放引用。例如,我希望使用下面的 'Free' 按钮释放 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();
}
}
点击'Free'按钮没有区别,点击new List<int>()
按钮会在二审时释放引用。即使我关闭 window.
,引用仍然存在
怎样才能顺利释放?
编辑: 它已被标记为可能与 Why Large Object Heap and why do we care? 重复,但在 .NET 4.7.1 上更改 LargeObjectHeapCompactionMode
无效。
我找到了解决方案,使用 ObservableCollection
而不是简单的 List
来回答原始问题,但我不知道这如何以及为什么会有所不同。出于左好奇心,我将这个问题悬而未决。
它是在当前删除的 blog post 上描述的。
The TextBlock control has a binding to an object (myGrid) that has a reference back to the TextBlock (it is one of myGrid children’s).
Note that this type of a DataBinding leak is unique to a specific scenario (and not to all DataBinding scenarios) as documented in the kb article. The property in the Path is a not a DependencyProperty and not on a class which implements INotifyPropertyChanged and in addition a chain of strong reverences must exist.
据此,我误用了数据绑定,正确的免费片段如下。
BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);
我想立即释放 ListView 的 ItemsSource 引用,以防引用占用大量内存。
但是即使我的代码中没有任何引用,GC 也不会释放引用。例如,我希望使用下面的 'Free' 按钮释放 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();
}
}
点击'Free'按钮没有区别,点击new List<int>()
按钮会在二审时释放引用。即使我关闭 window.
怎样才能顺利释放?
编辑: 它已被标记为可能与 Why Large Object Heap and why do we care? 重复,但在 .NET 4.7.1 上更改 LargeObjectHeapCompactionMode
无效。
我找到了解决方案,使用 ObservableCollection
而不是简单的 List
来回答原始问题,但我不知道这如何以及为什么会有所不同。出于左好奇心,我将这个问题悬而未决。
它是在当前删除的 blog post 上描述的。
The TextBlock control has a binding to an object (myGrid) that has a reference back to the TextBlock (it is one of myGrid children’s).
Note that this type of a DataBinding leak is unique to a specific scenario (and not to all DataBinding scenarios) as documented in the kb article. The property in the Path is a not a DependencyProperty and not on a class which implements INotifyPropertyChanged and in addition a chain of strong reverences must exist.
据此,我误用了数据绑定,正确的免费片段如下。
BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);