Laden...

Memory Leak bei ListView und ItemSource

Erstellt von Sieben vor einem Jahr Letzter Beitrag vor einem Jahr 537 Views
Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr
Memory Leak bei ListView und ItemSource

Hallo zusammen,

ich habe eine ListView die per ItemSource eine ObservableCollection bindet. Die ObservableCollection wird alle 2 Sekunden aktualisiert.
Dabei entstehen bei jeder Aktualisierung sehr viel neue WeakReference Objekte die nicht mehr abgebaut werden 🙁

Hier ist das ViewModel


public class SomeString : BaseViewModel
  {
    public SomeString ( string test )
    {
      m_test = test;
    }

    private string m_test = "AAA";

    public string SomeTest
    {
      get => m_test;

      set
      {
        m_test = value;

        OnPropertyChanged ( nameof ( SomeTest ));
      }
    }
  }

  public class MainWindowViewModel : BaseViewModel
  {
    public ObservableCollection<SomeString> SomeList { get; set; } = new ObservableCollection<SomeString> ();

    private Timer m_timer;

    public MainWindowViewModel ()
    {
      m_timer = new Timer ( new TimerCallback ( TimerCallback ));

      m_timer.Change ( 2000, 0 );
    }

    private void TimerCallback ( object state )
    {
      SomeList = new ObservableCollection<SomeString> ();

      SomeList.Add ( new SomeString ( "AAA" ));
      SomeList.Add ( new SomeString ( "BBB" ));
      SomeList.Add ( new SomeString ( "CCC" ));

      OnPropertyChanged ( nameof ( SomeList ));

      m_timer.Change ( 2000, 0 );
    }
  }

Hier ist das XAML dazu


<Window  x:Class="WPFTestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFTestApp"
        xmlns:vm="clr-namespace:WPFTestApp.ViewModels" xmlns:views="clr-namespace:WPFTestApp.Views"
        mc:Ignorable="d"
        Title="MainWindow" Height="700" Width="800">
  <Window.DataContext>
    <vm:MainWindowViewModel x:Name="ViewModel"></vm:MainWindowViewModel>
  </Window.DataContext>

  <Grid>
    <ListView ItemsSource="{Binding SomeList, Mode=OneWay}">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Text" DisplayMemberBinding="{Binding SomeTest, Mode=OneWay}" Width="200"></GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>
  </Grid>
</Window>

Mach ich hier irgendwas falsch was die Bindings betrifft?

Es ist eine .NET 6.0 WPF Application

Viele Grüße
Sieben

Nur die Kogge schwimmt! 😁

4.942 Beiträge seit 2008
vor einem Jahr

Hallo,

ich nehme an, du meinst die new SomeString("...")-Objekte.
Wie ermittelst du, daß diese Objekte nicht mehr (vom GC) gelöscht werden?

Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr

Ich habe im Visual Studio die Memory Usage ausgeben lassen und dort steigt der Speicher beständig an, siehe angehängte Bilder.
Ich vermute das es irgendwelche Bindings sind, die nicht ausgeräumt werden?!

Nur die Kogge schwimmt! 😁

4.942 Beiträge seit 2008
vor einem Jahr

OK, du meinst also wirklich die WeakReference-Objekte (welche von WPF intern beim Binding erzeugt werden).
Laut Internet-Suche gibt es einige Treffer dazu, aber ich habe keine konkrete Antwort dazu gefunden (außer OneWay-Binding zu verwenden, aber das machst du ja schon).
Wenn du testweise mal GC.Collect() im TimerCallback aufrufst, wie verändert sich dann die Memory-Auslastung?

Was mir aber gerade noch auffällt, ist, daß du anscheinend keinen DispatcherTimer benutzt, sondern einen Non-UI Timer. Ändere das mal und berichte dann.

Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr

Hab mein Code angepasst (DispatchTimer und GC), leider keine Änderung. Es werden immer noch jede Menge neuer Objekte generiert

Nur die Kogge schwimmt! 😁

16.842 Beiträge seit 2008
vor einem Jahr

Es ist nie gut die gebundene Liste neu zu erstellen, da Du damit auch die gebundene Referenz änderst.
Leer sie doch einfach?

Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr

Ich habe mein Code angepasst und die Liste wird jetzt geleert und neu befüllt. Leider gleiches Ergebnis.

Ich habe im WPF Github den Issue gefunden - traurig 🙁

Nur die Kogge schwimmt! 😁

Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr

Okay, außerhalb von Visual Studio tritt dieses Problem nicht auf. Also, Release gebaut, die Exe gestartet, Speicher bleibt im grünen Bereich. Es scheint also ein Visual Studio Problem beim Debuggen zu sein.

Thread kann daher geschlossen werden 🙂

Vielen Dank an alle Helfer!

Nur die Kogge schwimmt! 😁

16.842 Beiträge seit 2008
vor einem Jahr

War gerade dabei Dir zu antworten, weil ich den Issue überflogen hab.
Im Issue steht ja auch, dass es wohl ein VS Bug ist; der Issue ist verlinkt => https://developercommunity.visualstudio.com/t/Using-Hot-Reload-in-WPF-project-in-VS-20/1591986

Hast übersehen, als Du dort gepostet hast? 🙂

Sieben Themenstarter:in
140 Beiträge seit 2006
vor einem Jahr

Hast übersehen, als Du dort gepostet hast? 🙂

Ja ;D

Wobei der Tomasfil ja scheinbar immer noch das Problem hat und seine Anwendungen laufen scheinbar mehrere Tage/Wochen am Stück?!

Nur die Kogge schwimmt! 😁