0

My wpf application memory getting bigger and bigger when I keep use it.

so I want to create a simple one to see if it will release memory:

  1. create a wpf project
  2. put a ListBox bound collection and 2 Buttons for Load & clear data
  3. create an model Person
  4. create an observableCollection
  5. Load command is load 100,000 persons in to collection
  6. Clear command call ObservableCollection.Clear() method.
  7. check memory while these steps

XAML:

<DockPanel>
    <UniformGrid Rows="1" Columns="2" DockPanel.Dock="Bottom">
        <Button Content="Load" Padding="0,12" Command="{Binding LoadCommand}"/>
        <Button Content="Clear" Padding="0,12" Command="{Binding ClearCommand}"/>
    </UniformGrid>
    <ListBox ItemsSource="{Binding Persons}"/>
</DockPanel>

Person Model:

public class PersonModel : BindableBase
{
    private int _id = 0;
    public int ID { get { return _id; } set { SetProperty(ref _id, value); } }

    private string _name = string.Empty;
    public string Name { get { return _name; } set { SetProperty(ref _name, value); } }

    public override string ToString()
    {
        return $"{ID:00000} : {Name}";
    }
}

ViewModel:

public MainViewModel()
{
    Persons = new ObservableCollection<PersonModel>();
    Persons.CollectionChanged += (s, e) => {
        LoadCommand.RaiseCanExecuteChanged();
        ClearCommand.RaiseCanExecuteChanged();
    };
}

public ObservableCollection<PersonModel> Persons { get; private set; }

private BindableCommand _loadCommand = null;
public BindableCommand LoadCommand { get { return _loadCommand ?? (_loadCommand = new BindableCommand(LoadExecute, LoadCanExecute)); } }

private BindableCommand _clearCommand = null;
public BindableCommand ClearCommand { get { return _clearCommand ?? (_clearCommand = new BindableCommand(ClearExecute, ClearCanExecute)); } }

private void LoadExecute()
{
    if (!LoadCanExecute())
        return;

    for (int i = 0; i < 1000000; i++)
    {
        Persons.Add(new PersonModel { ID = i, Name = "The quick brown fox jumps over a lazy dog." });
    }
}
private bool LoadCanExecute()
{
    if (Persons.Count > 0)
       return false;

    return true;
}

private void ClearExecute()
{
    if (!ClearCanExecute())
        return;

    Persons.Clear();
}

private bool ClearCanExecute()
{
    if (Persons.Count == 0)
        return false;
    return true;
}

when I start the program(release version), memory usage in Task Manager is about 10mb(Test12.exe process)

enter image description here

when I click load button, memory raise to about 40mb:

enter image description here

but when I click Clear button, memory not trying to go back start size(10mb), but just stay in 39mb, I wait for 10 minutes it won't come down.

enter image description here

So my question is: how to release memory in WPF correctly?

Oh My Dog
  • 781
  • 13
  • 32
  • 1
    task manager is not accurate, and has such issue(bigger and bigger memory), suggest try **perfmon** instead. – Lei Yang Apr 25 '17 at 01:26
  • Task Manager is accurate, in that it shows your process memory allocations. But, it doesn't show you what your _code_ is using. You need a memory profiler for that. The .NET runtime allocates memory from the OS on your behalf, to fulfill your own code's _managed_ allocation requests. When your own code's objects are collected back after you are no longer using them, the runtime does _not_ immediately give that memory back to the OS. There are lots of questions on Stack Overflow already discussing this behavior. – Peter Duniho Apr 25 '17 at 02:50

0 Answers0