Переполнение памяти программы - C#

Узнай цену своей работы

Формулировка задачи:

Пишу программу для парсинга одного сайта. Сам сайт парсится с помощью CsQuery. Нужно за раз обработать нужный диапазон страниц сайта. Задаётся начальная и конечная ссылки для парсинга и программа в несколько потоков перебирает все страницы в диапазоне и извлекает нужную информацию в List, что бы после окончания сохранить всё в файл. Нужное количество потоков запускается, и они по очереди берут из счётчика текущей страницы свой номер и работают с ним. В потоках написан цикл While, что бы они не закрывались, пока не спарсили последнюю страницу. После окончания парсинга отдельно сохраняется вся информация в List. Но проблема в том, что парсится будут большие диапазоны страниц больше миллиона, а при тестовом запуске на диапазоне в 10 000 страниц программа начинает занимать в памяти больше 1,5 гигабайт. В отдельной программе пробовал заполнять List случайными данными, по типу тех, что должны были быть извлечены. Добавил 100 000 строк, и размер оперативной памяти, используемой программы не превышал 100 мегабайт. Парсинг так же работает правильно, никаких избыточных данных он не добавляет. Я грешу на мою неправильную работу с потоками, и то, что сборщик мусора не уничтожает данные с прошлых проходов парсинга. Пробовал разные способы так и не решил проблему с утечкой памяти. Помогите найти ошибку, или подсказать более правильный метод работы с потоками. Код прикладываю.
class Program
    {
        static int begin_of_post = 2950774;      //начальный индекс постов
        static int end_of_post = 2951774;        //конечный индекс
        static int current_post;                 //текущий пост для потоков
        
        static List<string> list_posts = new List<string>();   //список хранения данных о постах

        static void Main(string[] args)
        {
            ServicePointManager.DefaultConnectionLimit = 1000000000;   // количество одновременных соединений
 
            current_post = begin_of_post;
 
            Thread my_tr;                               
            for (int i = 0; i < 10; i++)            //запуск потоков
            {
                my_tr = new Thread(parse_site);
                my_tr.Start();
            }
 
            Console.ReadLine();
            save_to_file();
        }
 
        static void parse_site()
        {
            while (current_post <= end_of_post)
            {
                int link_to_post =current_post;                 //ссылка на пост
                Interlocked.Increment(ref current_post);        //инкремент счётчика
 
                CQ cq;
                try
                {
                    cq = CQ.CreateFromUrl("http://site.ru/" + link_to_post);        // загрузка кода страницы
                }
                catch
                {
                    Console.WriteLine("Error " + link_to_post);
                    continue;
                }
                
                string post_info;
                ...
                //сам парсинг сайта
                ...
                
                int current = int.Parse(link_to_post) - begin_of_post;          
                int end = end_of_post - begin_of_post;
                Console.WriteLine("Обработана ссылка " + current.ToString() + " ИЗ " + end.ToString());
                                                
                Thread my_tr_save=new Thread(save_post);
                my_tr_save.Start(post_info);
            }
        }

        static void save_post(object post_info)
        {
            ...
            // Парсинг информации о странице
            ...
            
            lock (list_posts)
            {
                list_posts.Add(post_info.ToString());
            }
        }      
 
        static void save_to_file()
        {
                        ...
            //сохранение строк list_posts в файл
                        ...
        }
    }

Решение задачи: «Переполнение памяти программы»

textual
Листинг программы
        static void save_post(object post_info)
        {
            lock (list_posts)
            {
                list_posts.Add(post_info.ToString());
            }
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.333 из 5
Похожие ответы