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.