由于存在大量内存管理问题,Windows Phone 8.1中的媒体管道似乎已被破坏。
当您创建使用IMediaSource在Windows Phone Runtime 8.1中传输音频的后台音频应用时,应用的组件最终会在某些情况下抛出OutOfMemoryException甚至StackOverflowException。查看内存转储时,内部存在大量未收集的垃圾。
讨论已经开始于MSDN forums,并得出了这个结论。我已经创建了一个WPDev UserVoice suggestion,以便Windows Phone团队能够注意到这一点,但我仍然希望我(以及来自MSDN论坛的其他人)谁错了并且有解决方案。
我还有一个小CodePlex project,也有这个问题,实际上有一个issue report关于这个确切的问题。
我希望在社区的帮助下,这个问题可以解决或直接传递给Microsoft开发团队进行调查和消除。谢谢!
更新1:
有一个kind of workaround for StackOverflowException,但它对OutOfMemoryException无效。
答案 0 :(得分:2)
好的,似乎这个问题实际上是在.NET中使用字节数组的生命周期。
为了解决内存问题,请使用Windows Runtime的Windows.Storage.Streams.IBuffer
。不要以任何形式创建许多新的.NET字节数组,既不是简单的new byte[]
,也不是使用System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBuffer
类,因为它是{{>> 的{{em>}实现1}} interface。
由于被IBuffer
结构固定并且溢出后台音频任务的内存阈值,这些字节数组一旦被分配,就会长寿。 OverlappedData
s(真正的 Windows运行时版本,如Windows.Storage.Streams.Buffer
类)包含仅在IBuffer
引用计数后才被释放的本机数组达到0(零),他们不依赖GC。
我发现的是这个问题不仅仅是背景音频特有的。实际上,我已经看到很多关于类似问题的其他问题。解决方案是尽可能使用Windows运行时后端,因为它不受管理,只要它们没有引用就会释放资源。
感谢@Soonts指出我正确的方向!
答案 1 :(得分:1)
他们对MSS管理内存的方式存在内存问题,但他们在更新过程中默默地修复了它:WP7 Background Audio - Memory Leak or Not?
我不确定,但我认为问题是你的代码。每次请求样本时,您都不应该调用var buffer = new byte[4096];
。这样做可能适用于PC,但对于嵌入式平台,我认为强调内存管理器并不是一个好主意。
在我的MediaStreamSource实现中,我使用在构造MSS时分配的单个循环缓冲区,并且在回放期间无限次地重用缓冲区的各部分。在我的GetSampleAsync中,我构造了一个我的Stream实现类的实例,它不拥有任何内存,而只是保存对该循环缓冲区的一部分的引用。这样,在播放过程中只分配/取消分配了几个小对象,因此音频流数据不会加载内存管理器。