Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.83
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
#1

Освобождение памяти в потоках - C#

03.01.2012, 13:07. Просмотров 2878. Ответов 8
Метки нет (Все метки)

Доброго времени суток. Помогите пожалуйста, товарищи программисты. Приложение может создавать от 1 до N параллельных одновременно работающих потоков (стандартно до 10-15) по ОДНОМУ НАПРАВЛЕНИЮ. "Одно направление" - это тоже поток. Направлений до 10. То есть я имею порядка 10 потоков, внутри каждого из которых создаётся ещё масса потоков, но что бы не убить систему сразу, используется пул потоков, который контролирует максимально возможное кол-во работающих потоков одновременно. Проблема в том, что по задумке внутренние потоки создаются, и, доходя до своего логического конца, самоуничтожаются (так я думаю), но беда в том, что объём используемой оперативной памяти, не смотря на это, только растёт, и растёт довольно быстро. Так вскоре забивается вся оперативная память (6 гб) и я даже не знаю что и делать... Такое впечатление, что потоки после завершения работы, используемые ресурсы не удаляют за собой (либо сборщик мусора не делает этого).

Как бы то ни было, потоки создаются и успешно завершаются в пуле, но память продолжает забиваться и забиваться, без освобождения... Помогите пожалуйста, что с этим можно сделать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2012, 13:07
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Освобождение памяти в потоках (C#):

Освобождение памяти - C#
Подскажите, пожалуйста, я ещё зелёный в C#. Есть у меня класс Form1, при определённом событии в нём я создаю екземпляр класса Sposob и...

Выделение/освобождение памяти - C#
помогите пожалуйста, в С++ есть конструкции вида xx=AllocMemInt2D(LL, NN); DeAllocMemFloat2D(LL, x); которые выделяют и освобождают...

Выделение и освобождение памяти - C#
Здравствуйте, помогите пожалуйста разобраться. Скажите является ли следующий код правильным в отношении перевыделения памяти, то есть не...

Освобождение памяти от переменных (или динамические переменные) - C#
Здравствуйте! Подскажите пожалуйста одну такую деталь: Вот в C/C++, мы объявляли динамические переменные и массивы при помощи...

Освобождение памяти - C#
Есть форма, из которой вызывается дочерняя форма, на дочерней форме есть пикчербокс, так вот, при вызове из главной в этот пикчербокс...

Освобождение оперативной памяти при использовании Awesomium - C#
Всем привет! Работаю с Awesomium, и всё было хорошо, пока я не открыл диспетчер задач. После обновления страниц в нем постоянно растет...

8
kolorotur
Эксперт .NET
9845 / 8223 / 1382
Регистрация: 17.09.2011
Сообщений: 14,131
03.01.2012, 13:21 #2
Дело, скорее всего, не в потоках, а в том, что вы где-то храните ссылки на создаваемые объекты, которые потом не выходят из области видимости, в результате чего сборщик их не подчищает.

Покажите код - будет намного проще разобраться в проблеме.
0
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
03.01.2012, 13:44  [ТС] #3
Код большой, и я боюсь, что вы не разберётесь, я ещё не везде комменты поставил... Вот, попробуйте пожалуйста: KataLOG.rar (не знаю как правильно прикручивать файлы, сделал так)
0
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
03.01.2012, 13:59  [ТС] #4
Смысл программы такой:
1. "заходит" на сайт интернет-магазина, списывает "каталоги" в checklistbox1 и предлагает пользователю выбрать, какие необходимы каталоги. После выбора работа продолжается с выделенными каталогами.
2. на каждый каталог создаётся поток в котором:
2.1. заходит на страничку каталога, находит товар на странице. Нашел - отправляет ссылку на этот товар в ещё один новый поток:
2.1.1. этот поток находит всю необходимую инф-ю и добавляет её в БД
2.2. ищет ещё товары, которых обычно ооочень много

p.s. пул потоков реализован вручную (знаю что очень некрасиво и некачественно, но дело не в нём).
0
kolorotur
Эксперт .NET
9845 / 8223 / 1382
Регистрация: 17.09.2011
Сообщений: 14,131
04.01.2012, 10:47 #5
Цитата Сообщение от Mans7 Посмотреть сообщение
Код большой, и я боюсь, что вы не разберётесь
Да не смешите. 600 строк - это уровень чуть выше "Hello world".

Я не буду комментировать организацию и синхронизацию (точнее, ее отсутствие) потоков - вы ее сами хорошо описали в своем последнем сообщении, но вот что сразу же бросается в глаза - это создание кучи соединений с БД и веб-клиентов, ресурсы которых не освобождаются должным образом через вызов методоа Dispose.
Например:
C#
1
2
WebClient wc3 = new WebClient();
WEBtext3 = wc3.DownloadString(sTovarURL);
надо бы сделать так:
C#
1
2
using (WebClient wc3 = new WebClient())
   WEBtext3 = wc3.DownloadString(sTovarURL);
Я с API под VistaDB не работал, но у меня сильнейшие подозрения, что там делать надо точно так же:
C#
1
2
3
4
5
6
7
8
9
10
using (VistaDBCommand SQLThreadCommand = MyConnection.CreateCommand())
{
   SQLThreadCommand.CommandText = "INSERT INTO Katalogs (KatalogName, KatalogURL) ";
   SQLThreadCommand.CommandText += "VALUES (@KN,@KURL)";
   SQLThreadCommand.Parameters.Add("@KN", VistaDB.VistaDBType.Text);
   SQLThreadCommand.Parameters[0].Value = sKatalogName;
   SQLThreadCommand.Parameters.Add("@KURL", VistaDB.VistaDBType.Text);
   SQLThreadCommand.Parameters[1].Value = sKatalogURL;
   SQLThreadCommand.ExecuteNonQuery();
}
Сделайте должное освобождение ресурсов во всех местах, где используется WebClient и работа с базой и попробуйте протестить снова.

Возможно, в коде имеются еще скрытые утечки, связанные с "потерянными" потоками. Это легко проверить, включив в диспетчере задач колонку "Threads" и наблюдая за количеством потоков.
Если оно постепенно растет, значит какой-то поток не завершается или теряется.
1
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
04.01.2012, 13:31  [ТС] #6
Сделал как Вы порекомендовали, но память как росла вверх неумолимо, так и растёт... Возможно лишь теперь не так быстро, но толку от этого мало =(...

Добавлено через 18 минут
Судя по монитору процессов, количество потоков достигает некоторого значения (при двух направлениях 21-29) и не превышает его. То есть процессы успешно закрываются, но, память не освобождается.

Попытался внести GC.Collect() - не помогает.
0
kolorotur
Эксперт .NET
9845 / 8223 / 1382
Регистрация: 17.09.2011
Сообщений: 14,131
04.01.2012, 13:32 #7
Прицепите код с внесенными изменениями - будем смотреть что дальше.
0
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
04.01.2012, 13:40  [ТС] #8
Что-то мне подсказывает что придется всю программу с нуля делать заного и теперь уже что-то новое учитывать... в данном случае - память... уже 4-й или 5-й раз будет, сбился со счета...

Попробовал использовать Dispose на объекты классов типа Webclient - безрезультатно.
0
Вложения
Тип файла: rar KataLOG.rar (5.5 Кб, 18 просмотров)
Mans7
59 / 59 / 2
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
04.01.2012, 14:41  [ТС] #9
Нашел интересную информацию:
http://www.gotdotnet.ru/forums/2/124760/588405/#post588405

Добавил себе
C#
1
2
3
4
using System.Runtime.InteropServices;
  [ DllImport( "kernel32.dll" ) ]
  public static extern bool SetProcessWorkingSetSize( IntPtr handle,
int minimumWorkingSetSize, int maximumWorkingSetSize );
И вставил в начало fThreadTov
C#
1
SetProcessWorkingSetSize( System.Diagnostics.Process.GetCurrentProcess().Handle,-1, -1 );
И вижу следующие изменения - программа так же притормаживает (это терпимо), а вот память плавно доходит до 20-30, потом падает до 5-10, доходит до 50, падает до 10-15, в общем за несколько минут работы, потребляемая память в среднем держится на 10-30. Все цифры в мегабайтах.

Хотя, как утверждает диспетчер задач, приложение кушает 50% ЦП. Система работает без изменений... Интересно - проблема решена? =)

Добавлено через 11 минут
До сих пор программулина работает в штатном режиме =) то есть всё достаточно стабильно держится и добавлено более 450 товаров в бд при обработке пока что одного только направления в котором 5-6 потоков. То есть суммарно приложение делает 7-8 потоков (1 основной главный поток, 1 первый параллельный на направление, 5-6 на товары направления). Все показатели без изменений. Вроде здорово.

Добавлено через 37 минут
Не знаю, будет ли продолжение темы, но, тем не менее, СПАСИБО большое, kolorotur, за помощь!
1
04.01.2012, 14:41
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2012, 14:41
Привет! Вот еще темы с ответами:

Произойдет ли освобождение памяти и сбор мусора в приложенном коде - C#
Подскажите пожалуйста, произойдет ли автоматическое освобождение памяти занимаемой экземплярами class_B и экземплярами class_C в случае...

.NET 4.x InvalidOperationException в потоках - C#
using System; using System.Collections.Generic; using System.Threading; using System.Linq; struct StaticThread { static...

Исключения в потоках - C#
Здравствуйте! Столкнулся со следующей проблемой: Написал класс, объект которого должен асинхронно устанавливать tcp-соединение с...

Ошибка в потоках - C#
Привет! помогите пожал! Есть ошибка в программе не могу ее исправить(( вот прога using System; using System.Text; using...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru