/ / Wyciek pamięci WPF - .net, wpf, wydajność, wycieki pamięci

WPF Memory Leak - .net, wpf, performance, wycieki pamięci

Mam formularz WPF, którego sam nie stworzyłem, więc nie jestem zbyt dobry w WPF. Jednak mocno przecieka, do 400 MB i zamknięcie formularza nie pomaga.

Problem polega na tym, że moja aplikacja ładuje wszystkozdjęcia na raz. Chciałbym załadować tylko te, które są w tej chwili widoczne. Jest to około 300 zdjęć i są one trochę duże, więc mój formularz WPF cierpi z powodu ładowania ich wszystkich.

mam DataTemplate z moim własnym typem, który ma właściwość Thumbnail. Kod w szablonie wygląda tak:

            <Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>

A potem mam siatkę z kontrolką, która mapowyższy szablon jako źródło. Kod tej kontrolki znajduje się poniżej. Proszę o wskazówki, jak zoptymalizować kod i być może uzyskać tylko te, które są widoczne i mają tylko tyle kontrolek załadowanych w tym samym czasie?

    <Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:ElementFlow">
<Grid Background="{TemplateBinding Background}">
<Canvas x:Name="PART_HiddenPanel"
IsItemsHost="True"
Visibility="Hidden" />
<Viewport3D x:Name="PART_Viewport">
<!-- Camera -->
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="60"
Position="0,1,4"
LookDirection="0,-1,-4"
UpDirection="0,1,0" />
</Viewport3D.Camera>

<ContainerUIElement3D x:Name="PART_ModelContainer" />

<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport2DVisual3D
RenderOptions.CachingHint="Cache"
RenderOptions.CacheInvalidationThresholdMaximum="2"
RenderOptions.CacheInvalidationThresholdMinimum="0.5"/>
</Viewport3D>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Odpowiedzi:

2 dla odpowiedzi № 1

Czy kontrolka „ElementFlow” jest taka sama, jak opisano tutaj? Wygląda na to, że kontrola jest już korzystam z wirtualizacji, więc nie spodziewałbym się, że uzyska dostęp do właściwości Thumbnail niewidocznego elementu.

Jak modelujesz strukturę danychujawnia właściwość „Miniatura”? Czy możesz ustawić to tak, aby usługa żądała załadowania miniatury przy pierwszym dostępie? Być może wdrożenie tego z zapasową pamięcią podręczną (która utrzymuje miniatury ładowane przez pewien czas) rozwiązałoby problem.

EDYTOWAĆ

Mogłem założyć coś, czego nie powinienem.Czytając komentarze do drugiego posta, do którego dołączyłem, myślę, że może być tak, że publicznie dostępna wersja kontrolki ElementFlow w rzeczywistości nie implementuje wirtualizacji. Być może mógłbyś zarejestrować dostęp do właściwości „Miniatura” i określić, czy ta właściwość jest dostępna dla niewidocznych elementów.


4 dla odpowiedzi nr 2

Pierwszym miejscem, na które należy zwrócić uwagę, próbując znaleźć wycieki pamięci w aplikacji .NET, WPF lub nie, są obiekty, które subskrybują zdarzenia.

Jeśli obiekt X nasłuchuje zdarzenia wywołanego przezobiekt Y, a następnie Y przechowuje odniesienie do X. Niezależnie od zastosowanej metody wirtualizacji (lub usuwania), jeśli X nie anuluje subskrypcji zdarzenia Y, X pozostanie na grafie obiektów tak długo, jak Y, i nigdy nie otrzyma sfinalizowane i zebrane bezużyteczne. (Nawet jeśli implementuje IDisposable a ty wyraźnie dzwonisz Dispose na tym.)

Kiedy mówisz „zamknięcie formularza nie pomaga”, to wzbudza we mnie podwójną podejrzliwość: „spodziewałbym się, że ktoś zaimplementował właściwość obiektu na Window obiekt, a ten obiekt zasubskrybował jakieś wydarzenie. Więc zamykasz okno, ale nadal istnieje w grafie obiektów, ponieważ istnieje odwołanie do jednej z jego właściwości.

(Aby dać ci wyobrażenie, jak podstępne może to być: WinForms ToolStrip kontrolki subskrybują zdarzenia zmiany motywu systemu Windowskiedy staną się widoczne. Jest to świetne, ponieważ zmiana motywu komputera jest automagicznie odzwierciedlana w interfejsie użytkownika uruchomionej aplikacji. ToolStrip bez uprzedniego ustawienia Visible na false, będzie nadal odbierać zdarzenia zmiany motywu do momentu zakończenia działania aplikacji).

Może w tym pomóc program do profilowania pamięci - w ten sposób odkryłem, że moja aplikacja ma ich tysiące ToolStrip przedmioty w pamięci, chociaż myślałem, że wszystkie zostały zniszczone.


0 dla odpowiedzi № 3

Trudno jest zawęzić problem za pomocą samego fragmentu kodu. Możesz chcieć Visual Profiler jeśli jeszcze tego nie zrobiłeś.