2010-12-07 3 views
6

У меня есть приложение .Net Framework # 4.0, которое делает большое количество веб-запросов, используя классы WebRequest/WebResponse, поскольку я вижу, что у него есть утечка памяти (или, может быть, я что-то не так) I Написал некоторое небольшое простое приложение, демонстрирующее это:Ошибка WebRequest/WebResponse Ошибка памяти

class Program 
{ 

    public static void Main(string[] args) 
    { 
     while(true) 
     { 
      var webRequest = (HttpWebRequest)WebRequest.Create("http://www.gooogle.com"); 
      Init(webRequest); 
      using (var webResponse = (HttpWebResponse)webRequest.GetResponse()) 
      { 
       var responseStream = webResponse.GetResponseStream(); 

       responseStream.ReadTimeout = 30; 
       var streamReader = new StreamReader(responseStream, Encoding.UTF8); 
       var page = streamReader.ReadToEnd(); 

       streamReader.Close(); 
       streamReader.Dispose(); 

       responseStream.Close(); 
       responseStream.Dispose(); 

       webResponse.Close(); 

       Console.WriteLine("Done"); 

       //GC.Collect(); 
      } 
     } 
    } 

    private static void Init (HttpWebRequest webRequest) 
    { 
     webRequest.Method = "GET"; 
     webRequest.Host = "www.gooogle.com"; 
     webRequest.UserAgent = 
      "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.5; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E; InfoPath.3) chromeframe/5.0.375.62"; 
     webRequest.Accept = 
      "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"; 
     webRequest.KeepAlive = true; 
    } 
} 

только одно решение я придумал, это использовать GC.Collect() (без опознавательных знаков в примере), Все объект расположены, все потоки будут закрыты, это я что-то не хватает?

Я нашел что-то, но я не понимаю причину, если я минимизирую Консоль, использование памяти уменьшится и выглядит O.K, что может быть причиной этого - проблема с Conosole или WinForm, как я могу ее исправить?

+2

Как вы видите, что он имеет утечку памяти? – 2010-12-07 01:39:13

+3

Stream и StreamReader также реализуют IDisposable. – 2010-12-07 02:08:45

+3

, если GC.Collect() исправляет вашу утечку, это не утечка. Вполне нормально, что GC зависает от ресурсов, если нет необходимости их выпускать. Считаете ли вы последствия для работы при длительном использовании приложения? Из-за увеличения использования памяти что-либо не работает должным образом? Проанализировали ли вы использование памяти в течение длительного периода времени? – BrokenGlass 2010-12-07 02:27:43

ответ

1

Попробуйте это:

while (true) 
{ 
    var webRequest = (HttpWebRequest) WebRequest.Create("http://www.gooogle.com"); 
    Init(webRequest); 
    using (var webResponse = (HttpWebResponse) webRequest.GetResponse()) 
    { 
     using (var responseStream = webResponse.GetResponseStream()) 
     { 
      responseStream.ReadTimeout = 30; 
      using (var streamReader = new StreamReader(responseStream, Encoding.UTF8)) 
      { 
       var page = streamReader.ReadToEnd(); 
      } 
     } 

     Console.WriteLine("Done"); 
    } 
} 
0

Да, мы тоже нашли утечку. Решение ... будьте осторожны, что вы делаете с этой штукой. Подумайте, не используйте его. Я считаю, что у него есть ... проблемы (по крайней мере, в 3.5, предположительно другие версии тоже). О, и не забудьте сообщить об этом/проголосовать за это в Microsoft Connect.

4

Вы выделяете память в узкой петле. У вас, вероятно, нет утечки памяти, у вас плохое приложение (в том смысле, что он использует множество системных ресурсов без причины.)

Сборщик мусора не собирается прерывать ваш цикл, чтобы компактную освобожденную память, если только это не связано с давлением памяти. Простое исправление будет заключаться в том, чтобы ввести задержку между итерациями цикла (может быть так же просто, как Thread.Sleep, хотя я не рекомендую это делать.)

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

Смежные вопросы