Утечка памяти в приложении WPF из 30 строк - PullRequest
2 голосов
/ 31 января 2011

У меня есть простое приложение WPF, состоящее из окна с оранжевым прямоугольником и непрерывной анимации, которая изменяет радиус размытия, который применяется к прямоугольнику. В настоящее время это приложение проходит тестирование на двух компьютерах для диагностики утечки памяти, связанной с WPF, в более крупной программе.

На первом компьютере использование памяти постоянно поддерживает среднее значение, которое слегка колеблется с той же частотой, что и продолжительность анимации. Тестовая программа работает надежно более недели без утечки памяти. Этот компьютер работает под управлением Windows 7 32-разрядной.

На втором компьютере, использование памяти показывает то же циклическое поведение, однако ~ каждые 90 секунд использование памяти увеличивается примерно на 100 КБ. Это дополнительное увеличение никогда не восстанавливается, пока приложение работает. Ранее я запускал эту программу, пока все это приложение не использовало всю системную память! Анимированное свечение на прямоугольнике, потребляющем 4 ГБ ОЗУ! Этот компьютер работает под управлением Windows 7, встроенный 32-разрядный.

Между этими двумя платформами существует существенная разница в оборудовании, однако в обеих системах установлены новейшие драйверы для соответствующего оборудования.

Один и тот же скомпилированный exe-файл установлен на обоих компьютерах без отладчиков. Код XAML для приложения включен ниже:

<Window
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="WpfAnimation.MainWindow"
 x:Name="Window"
 Title="MainWindow"
 Width="640" Height="480">
 <Window.Resources>
  <Storyboard x:Key="Flash" AutoReverse="True" RepeatBehavior="Forever" FillBehavior="Stop">
   <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(BlurEffect.Radius)" Storyboard.TargetName="rectangle">
    <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="15">
     <EasingDoubleKeyFrame.EasingFunction>
      <ElasticEase EasingMode="EaseOut"/>
     </EasingDoubleKeyFrame.EasingFunction>
    </EasingDoubleKeyFrame>
   </DoubleAnimationUsingKeyFrames>
  </Storyboard>
 </Window.Resources>
 <Window.Triggers>
  <EventTrigger RoutedEvent="FrameworkElement.Loaded">
   <BeginStoryboard Storyboard="{StaticResource Flash}"/>
  </EventTrigger>
 </Window.Triggers>

 <Grid x:Name="LayoutRoot">
  <Rectangle x:Name="rectangle" Fill="#FFFFA400" Margin="113,93,125,101" Stroke="Red" RadiusX="10" RadiusY="10" StrokeThickness="5">
   <Rectangle.Effect>
    <BlurEffect KernelType="Box" Radius="0"/>
   </Rectangle.Effect>
  </Rectangle>
 </Grid>
</Window>

Этот код был создан на основе .net Framework 4.0. За этим XAML нет кода C #.

У кого-нибудь есть какое-нибудь возможное объяснение, почему у такой простой программы происходит утечка памяти?

Ответы [ 2 ]

1 голос
/ 01 февраля 2011

Включение программного рендеринга устранило утечку.Теперь в каждом событии Window_Loaded я включаю рендеринг программного обеспечения, используя следующий код:

public static void EnableSoftwareRendering(Visual visual)
        {
            try
            {
                HwndSource source = PresentationSource.FromVisual(visual) as HwndSource;
                HwndTarget target = source.CompositionTarget;
                target.RenderMode = RenderMode.SoftwareOnly;
            }
            catch
            { }
        }
0 голосов
/ 16 февраля 2019

Это Event handlers leak.

Один из ваших обработчиков StoryBoard подписывается на FrameworkElement.Loaded и будет сохранен до конца.

Я пытался удалить BeginStoryBoard так:

    <EventTrigger RoutedEvent="UserControl.Unloaded"  SourceName="CellControl">
        <RemoveStoryboard BeginStoryboardName="MouseEnterStoryBoard"/>
    </EventTrigger>

Но это не работает. Поэтому я не знаю, как это исправить до сих пор.

Ниже приведен след обработчика из dotMemory.

System.Windows.Media.Animation.BeginStoryboard._inheritanceContext ->
System.Windows.EventTrigger._routedEventHandler ->
System.Windows.RoutedEventHandler._target ->
System.Windows.EventTrigger+EventTriggerSourceListener
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...