MediaPlayer 中的内存泄漏

Memory leak in MediaPlayer

谁能解释一下为什么下面的程序内存不足?

class Program
{
    private static void ThreadRoutine()
    {
        System.Windows.Media.MediaPlayer player = new System.Windows.Media.MediaPlayer();
    }

    static void Main(string[] args)
    {
        Thread aThread;
        int iteration = 1;

        while (true)
        {
            aThread = new Thread(ThreadRoutine);
            aThread.Start();
            aThread.Join();

            Console.WriteLine("Iteration: " + iteration++);
        }
    }
}

公平地说,我得到的具体异常是 System.ComponentModel.Win32Exception,"Not enough storage is available to process this command." 异常发生在尝试创建新的 MediaPlayer 时。

MediaPlayer 未实现 IDisposable 接口,因此我不确定是否需要进行其他清理。我当然没有在 MediaPlayer 文档中找到任何内容。

我的 猜测 是创建的 Thread 对象没有及时进行垃圾回收。

正如您在评论中所述,您 在找到不涉及内存泄漏的解决方案方面运气不佳,我将此替代方案发布为一个答案,即使它不会尝试回答您原来的问题。

如果您改为使用 ThreadPool,它 (a) 运行得更快并且 (b) 不会崩溃。

class Program
{
    private static void ThreadRoutine(object state)
    {
        var player = new MediaPlayer();

        var iteration = (int)state;
        if (iteration % 1000 == 0)
        {
            Console.WriteLine("Executed: " + state);
        }
    }

    static void Main(string[] args)
    {
        for (int i = 0; i < 10000000; i++)
        {
            if (i % 1000 == 0)
            {
                Console.WriteLine("Queued: " + i);
            }

            ThreadPool.QueueUserWorkItem(ThreadRoutine, i);
        }
    }
}

在我的机器上,我可以在几秒钟内创建 1000 万个线程池线程。

Queued: 9988000
Queued: 9989000
Queued: 9990000
Queued: 9991000
Executed: 9989000
Executed: 9990000
Executed: 9991000
Executed: 9988000
Queued: 9992000
Executed: 9992000
Queued: 9993000
Queued: 9994000
Queued: 9995000
Executed: 9994000
Executed: 9993000
Queued: 9996000
Executed: 9996000
Executed: 9995000
Queued: 9997000
Executed: 9997000
Queued: 9998000
Executed: 9998000
Queued: 9999000
Executed: 9999000
Press any key to continue . . .

很久以前我有一个应用程序,它将数据渲染为图像,并将其放在 PictureBox 上作为结果,就像图形引擎的管道一样,...

和你的共同点,就是记忆力不足,是这样的,...

  • 66%
  • 67%
  • 68%
  • 69%
  • 70%
  • 71%
  • 72%
  • 73%
  • 74%
  • 70% -->自动垃圾收集
  • 71%
  • 72%
  • 73%
  • 74%
  • 75%
  • 76%
  • 77%
  • 78%
  • 79%
  • 80%
  • 81%
  • 77% -->自动垃圾收集
  • 78%
  • 79%
  • .

还有很多 自动垃圾收集 在高内存大约 90% 到 97%,... 但似乎还不够,在某些时候,大约 97% 和 98% 的系统(应用程序)因内存问题而崩溃...

所以我有了这个想法,每隔几帧调用一次垃圾收集器, 所以我这样做了: GC.Collect();

GC.Collect它自己太重了,当内存中的对象太多时,...但是当你没有留下太多对象时,它工作顺利,...

还有很多关于终结对象的事情,但我不确定它们是否正常工作,因为它们自然以 -> x = null

结尾

这意味着,我们打破了那个对象的 link,但这并不意味着我们在银河系周围的某个地方没有这个对象(例如,您可以用消息填充对象析构函数,然后查看离开那个对象它不会立即被销毁,它需要直到你关闭你的应用程序/调用 GC.Collect / 内存不足,或者可能是随机自动收集),......直到它被销毁,......所以,例如作为 "using" 指令,它自己调用 "Dispose" 方法,我们用 obj= null 填充我们的处理,...那么我不确定我是否应该建议你编写手动完成方法,但还有一件事......有一个 Marshal 对象,我不知道它来自哪里,如果它适用于所有对象,我看到一些程序员用它来释放对象,......,我不知道知道它是如何工作的,但它可能真的从我们的记忆中释放了对象,...

如果您没有发现任何有用的信息,我的第一个选择是调用 GC.Collect...

您还可以设置它的参数,因此它收集的对象比正常情况下少。

https://msdn.microsoft.com/en-us/library/xe0c2357%28v=vs.110%29.aspx

Release resources in .Net C#

我也没有完全阅读这篇文章,但似乎他有线程和内存问题: Freeing resources when thread is not alive