2015-05-29 5 views
8

Может кто-нибудь объяснить, почему в следующей программе заканчивается память?Утечка памяти в 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, «Не хватает памяти для обработки команды.» Исключение происходит при попытке создать новый MediaPlayer.

MediaPlayer не реализует интерфейс IDisposable, поэтому я не уверен, нужна ли другая очистка. Я определенно не нашел в документации MediaPlayer.

+0

К сожалению, рамки .NET 4.5. –

+5

Наверное, потому что вы создаете новые потоки, пока не исчерпаете память, если я не пропущу что-то здесь. – MikeTheLiar

+0

@mikeTheLiar сборщик мусора должен позаботиться об этом, все экземпляры теряют свои ссылки. –

ответ

0

Угадать является то, что созданные объекты Thread не являются мусором, собранным во времени.

Как вы заявляете в своем комментарии, что вам не повезло с поиском решения, которое не связано с утечкой памяти, я отправляю эту альтернативу в качестве ответа, даже если он не пытается чтобы ответить на ваш первоначальный вопрос.

Если вы используете ThreadPool вместо этого, он (а) работает намного быстрее и (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); 
     } 
    } 
} 

На моей машине, у меня неты проблем при создании 10 миллионов потоков пула потоков в течение нескольких секунд.

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 . . . 
1

Я имел приложение давно, которое делало данные изображения, и поставил его над 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

которые означают, мы сломали связь с этим объектом, но это не значит, что мы делаем не иметь этого объекта где-то вокруг галактики (например, вы можете заполнить объект-деструктор сообщением и увидеть, что после его оставления он не будет немедленно уничтожен, это займет до закрытия вашего приложения/вызова GC.Collect/Lack on memory , или, может быть, случайный автоматический сбор), ... unti l он разрушается, ... так, например, как «использующая» директива, он сам вызывает метод «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