2015-05-29 38 views
8

Ai đó có thể giải thích tại sao chương trình sau hết bộ nhớ?Rò rỉ bộ nhớ trong 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++); 
     } 
    } 
} 

Để công bằng, ngoại trừ cụ thể tôi nhận được là một System.ComponentModel.Win32Exception, "Không đủ lưu trữ có sẵn để xử lý lệnh này." Ngoại lệ xảy ra khi cố gắng tạo MediaPlayer mới.

MediaPlayer không triển khai giao diện IDisposable vì vậy tôi không chắc liệu có cần dọn dẹp khác không. Tôi chắc chắn không tìm thấy bất kỳ tài liệu nào trong tài liệu MediaPlayer.

+0

Xin lỗi, .NET framework 4.5. –

+5

Có lẽ vì bạn đang tạo chủ đề mới cho đến khi bạn hết bộ nhớ, trừ khi tôi thiếu một số thứ ở đây. – MikeTheLiar

+0

@mikeTheLiar các nhà sưu tập rác nên chăm sóc đó, các trường hợp tất cả lỏng lẻo tham chiếu của họ. –

Trả lời

0

My đoán là đối tượng Thread được tạo không phải là rác được thu thập kịp thời.

Như bạn đang nói trong nhận xét của mình rằng bạn không may mắn khi tìm kiếm giải pháp không liên quan đến rò rỉ bộ nhớ, tôi đăng câu trả lời này ngay cả khi không cố gắng để trả lời câu hỏi ban đầu của bạn.

Nếu bạn sử dụng ThreadPool thay vào đó, nó (a) chạy nhanh hơn nhiều và (b) không sụp đổ.

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); 
     } 
    } 
} 

Trên máy tính của tôi, tôi không có vấn đề tạo ra 10 triệu thread-hồ bơi trong một vài giây.

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

Tôi đã có một ứng dụng từ lâu, mà trả lại dữ liệu hình ảnh, và đặt nó trên một PictureBox như kết quả, giống như một đường ống của động cơ đồ họa, ...

Điều đồ điểm chung với bạn, là thiếu trí nhớ, nó giống như thế này, ...

  • 66%
  • 67%
  • 68%
  • 69%
  • 70%
  • 71%
  • 72%
  • 73%
  • 74%
  • 70%-> Auto rác Thu
  • 71%
  • 72%
  • 73%
  • 74%
  • 75%
  • 76%
  • 77%
  • 78%
  • 79%
  • 80%
  • 81%
  • 77%-> Auto rác Thu
  • 78%
  • 79%
  • .
  • .
  • .

Và rất nhiều Auto rác Thu tại bộ nhớ cao khoảng 90% xuống còn 97%, ... nhưng dường như nó vẫn chưa đủ, và tại một số điểm xung quanh 97% và hệ thống 98% (ứng dụng) đã gặp sự cố với bộ nhớ ...

vì vậy tôi đi kèm với ý tưởng này, để gọi bộ thu gom rác mỗi vài khung hình, vì vậy tôi đã thực hiện điều này: GC.Collect();

GC.Collect nó tự là nặng, cũng có khi có quá nhiều đối tượng bên trong bộ nhớ, ... nhưng khi bạn không để lại quá nhiều đối tượng, nó hoạt động trơn tru, ...

có cũng có nhiều điều về việc hoàn thiện các đối tượng, nhưng tôi không chắc liệu chúng có hoạt động đúng hay không, vì chúng tự nhiên kết thúc bằng -> x = null

có nghĩa là chúng tôi đã phá vỡ liên kết đến đối tượng đó, nhưng không có nghĩa là chúng ta không có đối tượng này một số nơi xung quanh thiên hà (ví dụ bạn có thể điền vào đối tượng destructor với một tin nhắn, và xem sau khi rời khỏi đối tượng đó sẽ không bị phá hủy ngay lập tức, nó cho đến khi bạn đóng ứng dụng của bạn/gọi GC.Collect/Lack vào bộ nhớ , hoặc có thể thu thập tự động ngẫu nhiên), ... unti l nó bị phá hủy, ... như vậy, ví dụ như chỉ thị "sử dụng", nó tự gọi là "Vứt bỏ" phương pháp, và chúng tôi điền vào xử lý của chúng tôi với obj = null, ... sau đó tôi không chắc chắn nếu tôi nên giới thiệu bạn viết phương pháp hoàn thiện thủ công, nhưng vẫn có một thứ ... có một đối tượng Marshal, mà tôi không biết nó đến từ đâu, và nếu nó hoạt động trên tất cả đối tượng, tôi thấy một số lập trình viên sử dụng nó để giải phóng các đối tượng, .. ., tôi không biết nó hoạt động như thế nào, nhưng nó có thể thực sự giải phóng đối tượng khỏi kí ức của chúng ta, ...

Nếu bạn không tìm thấy bất cứ điều gì hữu ích về nó, lựa chọn đầu tiên của tôi sẽ được gọi GC.Collect ...

bạn cũng có thể thiết lập nó là thông số, vì vậy nó thu thập ít đối tượng, hơn nó sẽ làm như thường lệ.

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

Release resources in .Net C#

tôi cũng không đọc đầy đủ, nhưng dường như ông có chủ đề và bộ nhớ vấn đề: Freeing resources when thread is not alive