| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Parallel.For. Проблемы с памьятью. |
| Автор: Bladerender 14.3.2008, 12:50 |
| Помогите пожалуйста. Опытным путем было вычислено, что память девается именно при использовании паралелизма. Код имеет такой вид. GetSubTextInformation() - тут находится парсер, который парсит текстовую информацию и возвращает уже готовый результат. Получается, что память уходит в никуда и такими обьемами что просто ужасть. Parallel.For(0, textParts.Count, delegate(int i) { article[i] = parse.GetSubTextInformation(textParts[i], _textId, i + 1); }); При замене на просто for все становится как надо, никто никуда не ищезает, все очищается, и прога при роботе не превышает в памяти размера в 25 метров. Если с паралельностью то доходит до гига и потом каюк. Слышал что для каждого потока создается как бы своя куча, (я думаю там мусор и накапливается). Но немогу понять как это сделать. пробовал: Parallel.For(0, textParts.Count, delegate(int i) { using(Article article = parse.GetSubTextInformation(textParts[i], _textId, i + 1)) article[i] = article; }); все рано галяк. Пробовал так же внутри цыкла вызывать GC.Collect() но все равно безрезультатно. Помогите. |
| Автор: marcusmae 14.3.2008, 19:14 |
| Bladerender, похоже, что память съедают не фигурные скобочки, так что без кода парсера тут нечего сказать. |
| Автор: Bladerender 19.3.2008, 11:53 |
| Код парсера возвращает коллекцию строк. Тоесть класс, обьект которого возвращается имеет вид типа: class Name { public string Name; public List<string> collection = new List<string>(); } |
| Автор: marcusmae 19.3.2008, 12:16 |
| Bladerender, вероятно, какая-то проблема с разделяемостью ресурсов или thread-safety. Кстати, вместо String-массива пользуйтесь StringBuilder, когда создаёте строку. Это - общие соображения. А конкретно я бы попробовал-таки разделить ресурсы, то есть либо сделать парсер статическим, либо создать его экземпляров по числу вычислительных потоков и поставить в Parallel.Do. С другой стороны покрутите и свой вариант - всегда же можно вместо некоторых кусков кода наставить временных заглушек и тем самым локализовать проблему. |
| Автор: Bladerender 25.3.2008, 14:15 |
| Делал статическим, один перец. Нащет Parallel.Do, то пока не пробовал, но думаю что это все равно ничего не даст, так как потоки сами создают в Parallel.For по екземпляру на поток. Я в этьм почти уверен. |
| Автор: rubbiroid 26.3.2008, 01:22 |
| Не знаю, может поможет. Если у тебя внутри потока есть цикл, в котором создаются объекты - то сборщик мусора "старые" объекты удалит только после выхода из цикла. У меня такое было на загрузке фоток - вплоть до вываливания в нехватку памяти (когда более 2 гигабайт съедало). Мне помогло собственноручное удаление объктов внутри цикла. |
| Автор: marcusmae 27.3.2008, 01:00 | ||||
| Bladerender, окей, я для примеру написал генератор строк
и параллельно-последовательный тест с ним :
И ничего, апокалипсиса не наступило : в обоих случаях пик памяти - примерно 55 мб. Я может, поскромничал, нужны более агрессивные условия? |
| Автор: Bladerender 27.3.2008, 17:53 |
| Странно как-то получается. У меня Ваш код тоже работает нормально. Без апокалипсиса. Я разберусь что не так и вкину свой генератор. |
| Автор: marcusmae 27.3.2008, 22:09 |
Зачем же сразу выкидывать?! = Дайте его потестить, что ли... |