【问题标题】:Memory leak in dwm (Desktop Window Manager) using Animations in UWP使用 UWP 中的动画在 dwm(桌面窗口管理器)中发生内存泄漏
【发布时间】:2021-05-09 16:18:26
【问题描述】:

我为 UWP 编写了一个音乐播放器,它在播放音乐时使用一些动画,比如旋转封面。

我注意到桌面窗口管理器 (dwm.exe) 每秒消耗大约 1 MB 内存。上面显示的动画每秒消耗大约 300-400kb。关闭 App 不会释放内存。

暂停动画将停止韭菜。恢复它,它又开始泄漏了。

Animated 元素是这样定义的(完整文件在github):

<Ellipse
    x:Name="CoverDisc"
    Margin="{Binding ElementName=root, Path=ProgressThikness, Converter={StaticResource thiknessConver}, ConverterParameter={StaticResource thiknessParameter}}"
    RenderTransformOrigin="0.5,0.5"
    Stroke="{Binding ElementName=root, Path=BorderBrush}"
    StrokeThickness="{Binding ElementName=root, Path=ProgressThikness}">
    <Ellipse.Resources>
        <Storyboard x:Key="Storyboard">
            <DoubleAnimation
                RepeatBehavior="Forever"
                Storyboard.TargetName="transform"
                Storyboard.TargetProperty="Angle"
                To="360"
                Duration="0:0:20" />
            <!--  Duration="0:0:1.8" this is record spped  -->
        </Storyboard>
    </Ellipse.Resources>
    <Ellipse.RenderTransform>
        <RotateTransform x:Name="transform" />
    </Ellipse.RenderTransform>
    <Ellipse.Fill>
        <ImageBrush ImageSource="{Binding Cover, ElementName=root, TargetNullValue={StaticResource FallbackCover}}" Stretch="UniformToFill" />
    </Ellipse.Fill>
</Ellipse>

动画是通过代码控制的:

private static void IsPlayingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var me = d as NowPlayingDisk;
    var elipse = me.CoverDisc;
    if (elipse is null)
        return;
    var storyboard = elipse.Resources["Storyboard"] as Windows.UI.Xaml.Media.Animation.Storyboard;
    if ((bool)e.NewValue)
    {
        if (storyboard.GetCurrentState() == Windows.UI.Xaml.Media.Animation.ClockState.Stopped)
            storyboard.Begin();
        else
            storyboard.Resume();
    }
    else
        storyboard.Pause();
}

除了不使用任何动画来减少内存占用之外,我还能做什么?我注意到过去 dwm 消耗超过 7Gb,几乎不可能使用机器。

我现在使用这个应用程序有一段时间了,我不确定这个问题是否一直存在。它在过去确实运行了几个小时,至少我没有注意到任何消耗这么多内存的东西。

我在装有当前 Windows 版本的 Surface Pro 6 上运行:

Edition Windows 10 Home
Version 20H2
Installiert am  ‎16.‎10.‎2020
Betriebssystembuild 19042.964
Leistung    Windows Feature Experience Pack 120.2212.2020.0

Prozessor   Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz   2.11 GHz
Installierter RAM   16,0 GB
Systemtyp   64-Bit-Betriebssystem, x64-basierter Prozessor

编辑

我能够在另一台运行旧版本 Windows 的机器上对其进行测试。 在那台机器上,内存消耗完全没有问题。

Windows 10 Enterprise
Version 1908
Betriebssystembuild 17763.1879

【问题讨论】:

标签: c# uwp memory-leaks dwm


【解决方案1】:

如果在播放音乐时关闭应用程序,由于使用了内存的storyboard对象,可能会导致storyboard对象无法释放。因此,我建议您可以在附加到 App 类的 Suspending 事件中释放内存对象。如下:

public App()
{
    this.InitializeComponent();
    this.Suspending += App_Suspending;
}
private void App_Suspending(Object sender, SuspendingEventArgs e)
{
    storyboard.Pause();
}

【讨论】:

  • 谢谢。我会试试看。知道动画不断消耗它没有释放的内存吗?
  • 我已经测试了你的代码 sn-p,它在我的电脑上运行良好。当我播放动画时,它不会产生内存泄漏。如果你的设备比较多,可以在不同版本操作系统的电脑上测试,看看是否也出现这种情况,如果没有出现,可能与指定的电脑有关。
  • @Arya-ding-msft 我已经在另一台具有不同操作系统和处理器的 PC 上对其进行了测试。在那里我没有同样的问题。 (见编辑)。我需要在更多 PC 上对其进行测试.. 看看它是不是更常见的问题或只是我当前的设置。
  • 我的PC操作系统也是Windows10 20H2,但是我没有这种情况。一般不会发生这种内存泄漏,可能这个问题与你的电脑有关。
猜你喜欢
  • 2021-06-16
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多