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
谁能解释一下为什么下面的程序内存不足?
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