I have a simple wpf application. In main window i have stack panel and 2 buttons. First button adds 100 my user controls (without any data bindings, events, bitmaps), and second removes all of them from panel and calls GC.Collect(). And there are some problems: 1. After i clicked "remove" button first time not all my memory releases, and I must click it few times to release more memory. 2. After 5 - 10 min memory releases but few megabytes dont.
for example after my app starts it takes ~22mb when i adding 500 controls - ~60mb after i clicked "remove" button first time - ~55mb (I wait some time, memory not deallocated) i click few times and memory fell down to 25mb, I dont understand this, I am new in WPF, and maybe i miss something I want to release memory immediately.
<Window x:Class="WpfApplication10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="385" Width="553">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="240*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid
Name="border1"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" >
<ScrollViewer VerticalAlignment="Stretch"
Name="scrollViewer1"
HorizontalAlignment="Stretch">
<StackPanel
Margin="3,3,3,3"
Background="Transparent"
VerticalAlignment="Stretch"
Name="activityStackPanel"
HorizontalAlignment="Stretch">
</StackPanel>
</ScrollViewer>
</Grid>
<Button Content="Button" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="12,0,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Button Content="Button" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="141,0,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
<Label Content="Label" Grid.RowSpan="2" Height="28" HorizontalAlignment="Left" Margin="34,0,0,0" Name="label1" VerticalAlignment="Top" />
</Grid>
namespace WpfApplication10
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
int N = 100;
//var r = new ActivityStatisticItem("111", "222", DateTime.Now, "333", 1);
for (int i = 0; i < N; i++)
{
activityStackPanel.Children.Add(new UserControl1());
}
label1.Content = activityStackPanel.Children.Count;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
activityStackPanel.Children.Clear();
label1.Content = activityStackPanel.Children.Count;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
}
<UserControl x:Class="WpfApplication10.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="Transparent"
Margin="0,2,0,2"
MinHeight="80"
MinWidth="130"
MaxHeight="80">
<Grid Width="441">
<Grid.RowDefinitions>
<RowDefinition Height="40" Name="rowTop" />
<RowDefinition Height="40" Name="rowBottom"/>
</Grid.RowDefinitions>
<Border BorderBrush="Gray"
BorderThickness="1"
HorizontalAlignment="Stretch"
Background="LightGreen"
Name="contactPanel"
CornerRadius="3,3,3,3"
VerticalAlignment="Stretch" Panel.ZIndex="1" >
<Grid
VerticalAlignment="Stretch"
Name="grid1"
Margin="3,0,3,0"
HorizontalAlignment="Stretch">
<Label Content="Contact" Height="15" HorizontalAlignment="Left" Margin="15,3,0,0" Name="headerLabel" Padding="0" VerticalAlignment="Top" FontSize="10" FontWeight="DemiBold"/>
<Label Content="00/00/0000 00:00:00" Height="15" HorizontalAlignment="Left" Margin="13,18,0,0" Name="timeLabel" Padding="0" VerticalAlignment="Top" FontSize="10" Width="100" FontWeight="DemiBold" />
<Label Content="00:00:00" Height="15" HorizontalAlignment="Right" Margin="0,18,0,0" Name="durationLabel" Padding="0" VerticalAlignment="Top" FontSize="10" Width="38" FontWeight="DemiBold"/>
<!--<Image Height="12" HorizontalAlignment="Left" Margin="0,3,0,0" Name="directionPictureBox" Stretch="Fill" VerticalAlignment="Top" Width="12" />
<Image Height="12" HorizontalAlignment="Right" Margin="0,20,41,0" Name="timerImage" Stretch="Fill" VerticalAlignment="Top" Width="12" />
<Image Height="12" HorizontalAlignment="Left" Margin="0,20,0,0" Name="dateTimeImage" Stretch="Fill" VerticalAlignment="Top" Width="12" />-->
</Grid>
</Border>
<Border BorderBrush="Gray"
BorderThickness="1,0,1,1"
Grid.Row="1"
Background="White"
HorizontalAlignment="Stretch"
Margin="10,0,10,0"
Name="detailsPanel"
CornerRadius="0,0,3,3"
VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch"
Name="grid2"
Margin="3,0,3,0"
VerticalAlignment="Stretch">
<Label Content="Label" Height="15" HorizontalAlignment="Stretch" FontSize="9" Padding="0" Margin="0,3,0,0" Name="numberRadLabel" VerticalAlignment="Top" />
<Label Content="Label" Height="15" HorizontalAlignment="Stretch" FontSize="9" Padding="0" Margin="0,18,0,0" Name="queueRadLabel" VerticalAlignment="Top" />
</Grid>
</Border>
</Grid>
In user control i have only
public UserControl1()
{
InitializeComponent();
}
I want to release memory immediately.
Don't. Trust GC.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Don't. Trust GC.
After 5 - 10 min memory releases
Didn't I say trust GC?
Garbage collection model will make sure the unwanted managed memory in your system is released (which includes almost all of your controls memory). It uses an algorithm for optimising which includes generations, free memory available, possibly CPU available... so GC.Collect()
will interfere with it.
GC.Collect()
is asynchronous so no immediate effect.
The only resource you need to be careful is the unmanaged resource which usually is handled by Dispose Pattern. Otherwise don't mess with GC, it does its job very well.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
This is a surefire way of forcing non-GCable objects into Gen2 prematurely, thus increasing your memory footprint for a longer period of time, for no good reason.
As Aliostad said: don't!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With