none
C# Подскажите, пожалуйста, где в этой программе происходит «утечка памяти»? RRS feed

  • Вопрос

  • Продолжение темы:

    http://social.msdn.microsoft.com/Forums/ru-RU/programminglanguageru/thread/a85cda10-6d68-4f57-8fa4-747ec9e4fa13

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

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

    Все работает.

    Но, есть проблема. Через несколько часов работы эта программа съедает несколько Мб ОЗУ. А когда она съедает все ОЗУ компьютера, то компьютер глючит и зависает.

     

    На форме установлены такие контролы:

    1.  webBrowser1 - браузер

    2.  timer_Refresh - таймер

    3.  checkBox_Refresh - переключатель

    4.  notifyIcon1 – для прятанья проги в трей

     

    Подскажите, пожалуйста, где в этой программе происходит «утечка памяти»?

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    //using System.Net; //для проверки наличия сайта в инете HttpWebRequest
    
    namespace N_v._2
    {
        public partial class Form1 : Form
        {
            string address_start = @"http://www.Сайт.ru/";
            string address_planet = @"http://game.Сайт.ru/planet.php";
            string address_logout = @"http://game.Сайт.ru/logout.php";
            static Random objRandom = new Random();
            int num; //= objRandom.Next(35000, 780000);
            int caseSwitch = 0;
            public int hour, minute, time_R=30, time_KP, flag_fly;
    
            string strNemexi = "Сайт v.2 ";
            
            public Form1()
            {
                InitializeComponent();
    
                //if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                //    MessageBox.Show("Подключен");
                //    else MessageBox.Show("Нет");
                
    
                timer_Refresh.Enabled = true;
                this.ShowInTaskbar = false; //В конструкторе формы скрываем видимость приложения на панели задач при запуске
                // Handle the DoubleClick event to activate the form.
                notifyIcon1.Click += new System.EventHandler(this.notifyIcon1_Click);
                ((Control)webBrowser1).Enabled = false; //запретить использование веб-браузера
    
                this.webBrowser1.DocumentCompleted += (s, e) =>
                {
                    if (this.webBrowser1.ReadyState != WebBrowserReadyState.Complete)
                        return;
                    try
                    {
                        this.webBrowser1.Document.GetElementById("loginForm").Focus();
                        this.Activate();
     
                        //Выбор циклической вселенной
                        foreach (HtmlElement select in this.webBrowser1.Document.GetElementsByTagName("select"))
                        {
                            if (select.Name == "server_id" && select.GetAttribute("tabindex") == "1")
                            {
                                select.SetAttribute("value", "2");
                                break;
                            }
                        }
    
                        HtmlElementCollection pageTextElements = this.webBrowser1.Document.GetElementsByTagName("input");
                        switch (caseSwitch)
                        {
                            case 0:
                                 this.Text = strNemexi + "Пользователь 0";
                                 foreach (HtmlElement element in pageTextElements)
                                 {
                                     if (element.Name.Equals("email_or_login"))
                                         element.SetAttribute("value", "Пользователь 0"); //Ввод логина user
                                     if (element.Name.Equals("pass"))
                                         element.SetAttribute("value", "пароль 0"); //Ввод пароля pass
                                 }
                                 caseSwitch++;
                                 break;
                            case 1:
                                 this.Text = strNemexi + "Пользователь 1";
                                 foreach (HtmlElement element in pageTextElements)
                                 {
                                    if (element.Name.Equals("email_or_login"))
                                        element.SetAttribute("value", "Пользователь 1"); //Ввод логина user
                                    if (element.Name.Equals("pass"))
                                        element.SetAttribute("value", "пароль 1"); //Ввод пароля pass
                                 }
                                 caseSwitch++;
                                 break;
                            case 2:
                                 this.Text = strNemexi + "Пользователь 2";
                                 foreach (HtmlElement element in pageTextElements)
                                 {
                                     if (element.Name.Equals("email_or_login"))
                                         element.SetAttribute("value", "Пользователь 2"); //Ввод логина user
                                     if (element.Name.Equals("pass"))
                                         element.SetAttribute("value", "пароль 2"); //Ввод пароля pass
                                 }
                                 caseSwitch++;
                                 break;
                            ...
                            default:
                                 this.Text = strNemexi + " Пользователь N";
                                 foreach (HtmlElement element in pageTextElements)
                                 {
                                     if (element.Name.Equals("email_or_login"))
                                         element.SetAttribute("value", "Пользователь N"); //Ввод логина user
                                     if (element.Name.Equals("pass"))
                                         element.SetAttribute("value", "пароль N"); //Ввод пароля pass
                                 }
                                 caseSwitch = 0;
                                 break;
                        }
    
                        //Нажание кнопки "Вход"
                        foreach (HtmlElement button_enter in this.webBrowser1.Document.GetElementsByTagName("A"))
                        {
                            if (button_enter.InnerText == "Вход" && button_enter.GetAttribute("tabindex") == "4")
                            {
                                button_enter.RaiseEvent("onclick");
    
                                num = objRandom.Next(35000 * 10, 780000);
                                time_R = (int)((num / 1000)/10); //секунд на игрока
                                //timer_Refresh.Interval = time_R * 1000;
                              
                                timer_Refresh.Enabled = true;
                                checkBox_Refresh.Checked = true;
                                break;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        return;
                    }
                };
    
                try { this.webBrowser1.Navigate(new Uri(address_start)); }
                catch (System.UriFormatException) { return; }
            }
    
            private void checkBox_Refresh_CheckedChanged(object sender, EventArgs e)
            {
                if (checkBox_Refresh.Checked == true)
                {
                    timer_Refresh.Enabled = true;
                    if (time_R <= 0) time_R = 30;
                }
                else
                {
                    timer_Refresh.Enabled = false;
                    checkBox_Refresh.Text = checkBox_Refresh.Text + " Пауза";
                }
            }
    
            private void timer_Refresh_Tick(object sender, EventArgs e)
            {
                if (time_R == 10)
                {
                    try { this.webBrowser1.Navigate(new Uri(address_planet)); }
                    catch (System.UriFormatException) { return; }
                }
    
                if (time_R == 5)
                {
                    try
                    {
                        foreach (HtmlElement a in this.webBrowser1.Document.GetElementsByTagName("A"))
                        {
                            if (a.GetAttribute("title") == "Просканировать орбиту")
                            {
                                a.RaiseEvent("onclick");
                                //break;
                            }
                        }
                    }
                    catch (Exception) { return; }
                }
    
                if (time_R <= 0)
                {
                    try 
                    { 
                      this.webBrowser1.Navigate(new Uri(address_logout));
                      timer_Refresh.Enabled = false; //Выключаем таймер и выходим на страницу входа
                    }
                    catch (System.UriFormatException) { return; }
                }
                this.checkBox_Refresh.Text = "До обновления: " + (--time_R) + " сек";
                Application.DoEvents();
            }
    
            private void notifyIcon1_Click(object sender, EventArgs e)
            {
                // Set the WindowState to normal if the form is minimized.
                if (this.WindowState == FormWindowState.Minimized)
                    this.WindowState = FormWindowState.Maximized;
    
                // Activate the form.
                this.Activate();
            }
        }
    }
    
    

    6 февраля 2012 г. 19:06

Ответы

  • Учтечка возникает из-за использования компоненты WebBrowser, т.к. он грузит IE, и при множестве переходов память просто забивается, + утечка может быть на самой странице (javascript)

    Я бы посоветовал вам делать все без WebBrowser, посылая просто запросы

    Ну и самый простой вариант - все оставить как есть, с тем исключением, что лишь перезапускать периодически приложение:

    Application.Restart();

    или собирать мусор "самому":

    GC.Collect()

    Но последний вариант не решит всех проблем

    • Предложено в качестве ответа iSanSYS 8 февраля 2012 г. 8:17
    • Помечено в качестве ответа sg6336 9 февраля 2012 г. 8:26
    8 февраля 2012 г. 8:17

Все ответы

  • эта программа съедает несколько сотен Мб ОЗУ(была опечатка)

    6 февраля 2012 г. 19:18
  • С первого взгяда такое ощущение, что сам веб-браузер у вас забивает память, хотя такого быть не должно.

    Вы никакие данные во время работы никуда не сохраняете? Только загрузка страницы, ее анализ и переход на следущую?


    Для связи [mail]

    7 февраля 2012 г. 8:42
  • Ничего нигде не сохраняю.

    Это полный текст программы.

    Вот как она работает:
    1. Входит на главную страницу сайта.
    2. Вводит логин и пароль игрока. Нажимает «вход».
    3. На новой странице программа нажимает на ряд кнопок.
    4. Ждет выполнения сценариев, которые запускаются на этой странице после нажатия кнопок.
    5. Выходит на главную страницу сайта.
    6. Повторяет все это для следующего пользователя.

    Может память съедается куками? Но, тогда, почему ОЗУ?
    Есть какае-то команда, которая бы стирала куки перед входом следующего пользователя?


    • Изменено sg6336 7 февраля 2012 г. 11:25
    7 февраля 2012 г. 10:01
  • А сама игра случаем не на флеше сделана?

    Недавно столкнулся с тем, что одна браузерка на Flash при долгой игре постепенно отжирает всю память и либо вылетает плагин, либо сам браузер падает (как Firefox, так и Chrome).

    7 февраля 2012 г. 22:01
  • Насколько могу судить, игра не на флэше сделана.
    Как это можно проверить?
    Т.е. при просмотре html кода страницы, на что обратить внимание?
    Данная программа не обращается к флэшу. Только html элементы.
    Может тут какой-то принудительный вызов сборки мусора надо вызвать?
    8 февраля 2012 г. 7:12
  • "Утечка памяти" может возникать из-за множества переходов на новые страницы, посмотрите обсуждение на stackoverflow - How to Fix the Memory Leak in IE WebBrowser Control?

    Возможно у вас такая же проблема. Попробуйте предложенные там решения.


    Для связи [mail]

    8 февраля 2012 г. 7:15
  • Учтечка возникает из-за использования компоненты WebBrowser, т.к. он грузит IE, и при множестве переходов память просто забивается, + утечка может быть на самой странице (javascript)

    Я бы посоветовал вам делать все без WebBrowser, посылая просто запросы

    Ну и самый простой вариант - все оставить как есть, с тем исключением, что лишь перезапускать периодически приложение:

    Application.Restart();

    или собирать мусор "самому":

    GC.Collect()

    Но последний вариант не решит всех проблем

    • Предложено в качестве ответа iSanSYS 8 февраля 2012 г. 8:17
    • Помечено в качестве ответа sg6336 9 февраля 2012 г. 8:26
    8 февраля 2012 г. 8:17
  • Спасибо, так и сделал. Вроде работает.
    Пусть сутки пошуршит программа. Если переполнения памяти не будет, то помечу, как ответ Ваше предложение.
    8 февраля 2012 г. 12:42
  • > Подскажите, пожалуйста, где в этой программе происходит «утечка памяти»?


    см. Debug Diagnostic Tool v1.2 - для выявления утечек и т.д.
     
     

    8 февраля 2012 г. 19:29