UWP MediaPlayer(Windows.Media.Playback.MediaPlayer)上的内存泄漏

时间:2019-02-16 16:42:12

标签: xaml uwp

我正在维护WPF应用程序。我在项目中添加了UWP nedia播放器。但是,内存使用率太高。我意识到UWP媒体播放器已经做到了,所以我创建了可重复的代码。

while (true)
{
    var mp = new MediaPlayer()
    {
        Source = MediaSource.CreateFromUri(new Uri("Test.mp4"))
    };
    Thread.Sleep(1000);
    mp.Play();
    Thread.Sleep(1000);
    mp.Dispose();
}

此代码发生内存泄漏。我创建了MediaPlayer并将其丢弃!但是,它的内存使用量会无限增长。

如何在此代码上捕获内存泄漏?

这是.NET Core 3.0项目。 (带有WPF的XAML孤岛)我还没有测试它是否发生在纯UWP项目中。

有人说这很自然,因为这是一个循环。但是,下面的代码不会造成任何内存泄漏,因为GC有效。 (当然,不会收集某些(但有限制的)引用。)

while (true)
{
    new SomeClass();
}

2 个答案:

答案 0 :(得分:1)

代码写入内存的方式会膨胀并不断增长,直到内存用完为止。我也在纯UWP中进行了验证。如果进行以下两项更改,您会发现内存将保持稳定,并且每次循环后系统将回收所有内存:

  1. 还丢弃创建的MediaSource对象,并将其分配给Source属性
  2. 不要紧紧地运行它,而应将自己作为调度程序动作来调用

这是未显示任何泄漏的代码(在UWP中经过测试)。在WPF中,Dispatcher调用看起来会稍有不同:

private async void PlayMedia()
{
    var ms = MediaSource.CreateFromUri(new Uri("ms-appx:///Media1.mp4"));
    var mp = new MediaPlayer()
    {
        Source = ms
    };
    Thread.Sleep(1000);
    mp.Play();
    Thread.Sleep(1000);
    mp.Dispose();
    ms.Dispose();

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(PlayMedia));
}

作为旁注:如果SomeClass是纯托管代码类,则您提到的“ SomeClass”比较并不是完全一样,因为您在此处创建的对象是复杂的本机Windows运行时对象,周围只有一个薄的托管代码包装器。

现在也在WPF中进行了测试:我重现了原始的内存增长问题,然后应用了建议的更改并验证了内存不再增长。这是我的测试项目以供参考:https://1drv.ms/u/s!AovTwKUMywTNuLk9p3frvE-U37saSw

我也将WPF应用程序打包为Windows应用程序包运行your shared solution,但在最新发布的Windows 10版本(17763.316)上没有泄漏。下面是运行解决方案一段时间后的内存诊断屏幕截图。如果这是特定于您正在运行的内部人员构建的,请通过反馈中心记录错误。我认为在这一点上,我们应该按照回答结束这个问题。

enter image description here

答案 1 :(得分:0)

这绝对是Windows 10 19H1的错误。因为内置应用程序(电影和电视)具有相同的内存泄漏问题。要重现此内容,只需重复该打开的视频文件并关闭它即可。