I want to release ListView's ItemsSource reference immediately in case the reference holds large memory.
But GC doesn't release the reference even though I don't have any reference in my code. For example, I expected freeing byte[]
with the below 'Free' button.
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();
}
}
Clicking 'Free' button makes no difference, with new List<int>()
, it release the reference on second trial. The reference stays alive even if I close window.
How can I release it desirably?
EDIT: It had been marked possible duplicate of Why Large Object Heap and why do we care?, but changing LargeObjectHeapCompactionMode
on .NET 4.7.1 has no effect.
I found the solution, using ObservableCollection
instead of plain List
which answers original question but I don't know how and why this makes difference. For left curiosity I leave this question open.
It was described on a currently deleted 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.
According to that, I misused data binding, and correct free snippet is the below.
BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);