Утечки памяти, List And Http Request .net - PullRequest
0 голосов
/ 24 января 2012

У меня есть несколько вопросов по поводу утечки памяти.

В моем приложении winForm я использую TabControl с WebBrowser объектами, которые я размещаю без проблем.

Мне нужно использовать много List<T>, и 1 из них должен быть статическим, этоиспользует около 1000 2000 Strings (url), и его необходимо очищать и обновлять каждые 10 минут, в то время как другой список должен использоваться с новым элементом для каждого цикла.

Теперь я использовал память Dot Trace, чтобы выяснить причину утечки памяти.Это не говорит мне, какая функция вызывает его, для String он говорит, что не может найти PDB mscorilib.dll, а для Byte[] = Source не доступен для массива.

>  39,28% System.Byte [] Count = 22 Size = 615819 HeldCount = 22 HeldSize
>  = 615819 

>  27,06% System.String Count = 6370 Size = 424222 HeldCount = 6370 HeldSize = 424222 

    3,70% System.Object [] Count = 250 Size = 57992 HeldCount = 6206 HeldSize = 377523

(остальные живые объекты используют 2%3%)

Я читал об утечках памяти в каком-то вопросе о stackoverlow, и одной из многих ошибок является сохранение ссылочной переменной для List (для примера).

Теперь я бы понял: еслиэтот код вызывает утечку памяти 1)

private void ExampleLeaks()
    {
        List<String> example = new List<String>();
        example.add("foo");
        example.add("bar");
        return example;
    }

решение должно быть таким?

Class foo {
             List<String> example = new List<String>();
             private void ExampleLeaks()
              { 
                example.clear();
                example.add("foo");
                example.add("bar");
                return example;
              }
          }

2) Теперь я не понимаю, для чего используется byte[].Только байт, который я использую, находится в HttpWebRequest.Я сделал несколько подключений к веб-серверу, где я делаю логин, сохраняю Cookie и каждую 1 минуту использую CookieCollection от логина для обновления данных.

Я использую этот метод каждую 1 минуту

В основном классе я инициализирую StringBuilder buf = new StringBuilder();

 public String DoRequestWeb(String urls, String Method, String user, String data, String License, String Action)
                { 
                    Uri url = new Uri(urls);
                    HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(url);
                    _request.Method = Method;
                    _request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                    _request.AllowAutoRedirect = false; 
                    _request.CookieContainer = _cookieContainer;
                    _request.ContentType = "application/x-www-form-urlencoded";
                    _request.UserAgent = "SomeuserAgent";
                    _request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");  
                    string _postData; 
                   _postData = // Do Stuff 
                    byte[] _byteArray = Encoding.UTF8.GetBytes(_postData);
                    Debug.WriteLine(_byteArray.Count());

                    _request.ContentLength = _byteArray.Length; 

                    using (Stream _reqStream = _request.GetRequestStream())
                    {
                        _reqStream.Write(_byteArray, 0, _byteArray.Length);
                        _reqStream.Close();
                    }
                    buf.Clear(); 
                    using (HttpWebResponse _response = (HttpWebResponse)_request.GetResponse())
                    {
                        if (HttpStatusCode.OK == _response.StatusCode)
                        {
                            Debug.WriteLine("Status code " + _response.StatusCode);
                            using (StreamReader _reader = new StreamReader(_response.GetResponseStream(), Encoding.UTF8))
                            { 
                                char[] buffer = new char[256];
                                int count;
                                Debug.WriteLine("Buffer [] char count "+(buffer.Count()));
                                while ((count = _reader.Read(buffer, 0, 256)) > 0)
                                {
                                    buf.Append(buffer, 0, count);
                                }
                            }
                        }

                      } 
                    return buf.ToString(); 
                }

И 3)

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

Все Этот список инициализируется в классе

 //response contain a list of 1000 2000 links taken from a 
 //httpwebRequest and take data from XML Document webpage  and parse it into a list

    public List<MainForm.Links> GetListaCiclo(List<Links> response3)
    {                
                    listGoogle.Clear();
                    listYahoo.Clear();
                    listBing.Clear();
                    listOther.Clear();
                    //Other 4        
                    var rnd = new Random();
                    var q = from a in response3.GroupBy(l => new { l.idHost, l.Type })  
                            let col = a.ToList()
                            select col[rnd.Next(0, col.Count)];

                    foreach (Links str in q)
                    {
                        switch (str.idHost)
                        {
                            case 0: 
                                listGoogle.Add(str);
                                break;
                            case 1: 
                                listYahoo.Add(str);
                                break;
                            case 2: 
                                listBing.Add(str);
                                break;
                            case 3 
                                listOther.Add(str);
                                break; 
                            //Other 4 list 
                        } 
                     }

                    var google = listGoogle.OrderBy(x => rnd.Next()).Take(4);
                    var yahoo = listYahoo.OrderBy(x => rnd.Next()).Take(2);
                    var Bing = listBing.OrderBy(x => rnd.Next()).Take(1);
                    var otherSeacher = listOtherSeacher.OrderBy(x => rnd.Next()).Take(1);
                    //Other same 4  

                    tmp.Clear();
                    tmp = google.Where(h => h != null).ToList();
                    tmp.AddRange(yahoo.Where(h => h != null));
                    tmp.AddRange(bing.Where(h => h != null));
                    tmp.AddRange(other.Where(h => h != null)); 
                    .....other 4     
                    return tmp;
                }

ОБНОВЛЕНИЕ: 4) Как насчет Pinvoke?

 [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
        private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);
        const int URLMON_OPTION_USERAGENT = 0x10000001;

        private const int INTERNET_OPTION_END_BROWSER_SESSION = 42; 
        [DllImport("wininet.dll", SetLastError = true)]
        private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

        [DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

        [DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        internal static extern IntPtr GetCurrentProcess();

Я просто звоню им 1 раз в минуту.Я не знаю, может ли это привести к утечке памяти.

1 Ответ

0 голосов
/ 24 января 2012

По моему мнению, эти System.Byte [] и System.String являются обычными живыми объектами, а не утечками памяти. Этими объектами управляет сборщик мусора, и они удаляются, как только они не используются другими объектами.

private void ExampleLeaks () - ваш первый пример верен.

Возможной причиной, по которой вы пропускаете много памяти, являются объекты других типов, которые необходимо утилизировать, а вы их не утилизировали. Эти неразмещенные объекты, вероятно, содержат внутренние байтовые массивы и строки. Вам следует взглянуть на объекты HttpRequest / Response и т. Д. Я боюсь, что список памяти DotTrace вам здесь не поможет, или лучше сказать, что вы не можете прочитать его так просто - даже когда он говорит «byte []», вы должны смотреть на объекты разных типов, а не только байты []. потому что эти разные объекты могут иметь внутри себя байтовые [] массивы.

На самом деле, возможно, не имеет значения, являются ли эти предметы одноразовыми или нет. Пока они живы, в них есть некоторые другие объекты, такие как массивы байтов [] и строки.

...