4

由于很多内存管理问题,Windows Phone 8.1 中的媒体管道似乎被破坏了。

当您在 Windows Phone Runtime 8.1 中创建使用 IMediaSource 流式传输音频的后台音频应用程序时,该应用程序的组件最终会引发 OutOfMemoryException,在某些情况下甚至会引发 StackOverflowException。查看内存转储时,里面有很多未收集的垃圾。

讨论已在MSDN 论坛上开始,并进展到这个结论。我创建了一个WPDev UserVoice 建议,以便 Windows Phone 团队能够注意到这一点,但我仍然希望是我(和 MSDN 论坛的其他人)错了,并且有解决该问题的方法。

我还有一个小型CodePlex 项目也受此影响,实际上那里有一个关于这个确切问题的问题报告。

我希望在社区的帮助下,这个问题可以得到解决或直接传递给微软开发团队进行调查和消除。谢谢!

更新1:

StackOverflowException 有一种解决方法,但它对 OutOfMemoryException 没有帮助。

4

2 回答 2

2

好的,看来问题实际上在于.NET 中字节数组的生命周期。

为了解决内存问题,应该使用 Windows 运行时的Windows.Storage.Streams.IBuffer. 不要以任何形式创建许多新的 .NET 字节数组,无论是通过 simplenew byte[]还是通过使用System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferclass,因为它是接口的托管实现IBuffer

这些字节数组一旦被分配,就会因为被OverlappedData结构固定而寿命很长,并且会溢出后台音频任务的内存阈值。IBuffers (真正的Windows 运行时的,如Windows.Storage.Streams.Buffer类)包含本机数组,一旦IBuffer的引用计数达到 0(零),它们就会被释放,它们不依赖 GC。

我发现这个问题不仅是背景音频特有的。实际上,我已经看到了很多关于类似问题的其他问题。解决方案是在可能的情况下使用 Windows 运行时后端,因为它是非托管的,并且在资源为零时立即释放资源。

感谢@Soonts 为我指明了正确的方向!

于 2014-10-09T07:23:29.053 回答
1

他们在 MSS 管理其内存的方式上存在内存问题,但他们在一些更新期间默默地修复了它:WP7 背景音频 - 内存泄漏与否?

我不确定,但我认为问题出在您的代码上。您只是不应该在var buffer = new byte[4096];每次请求样品时都打电话。这样做可能适用于 PC,但对于嵌入式平台,我认为对内存管理器施加太大压力并不是一个好主意。

在我的 MediaStreamSource 实现中,我使用了在构造 MSS 时分配的单个循环缓冲区,并且缓冲区的部分在播放期间被无限重用。在我的 GetSampleAsync 中,我构造了我的 Stream 实现类的一个实例,它不拥有任何内存,而是只保存对该循环缓冲区的一部分的引用。这样,在播放过程中只有少数小对象被分配/释放,因此音频流数据不会加载内存管理器。

于 2014-09-06T16:15:12.697 回答