Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Parallel.For. Проблемы с памьятью. не могу понять 
V
    Опции темы
Bladerender
Дата 14.3.2008, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Помогите пожалуйста. Опытным путем было вычислено, что память девается именно при использовании паралелизма.
Код имеет такой вид.  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() но все равно безрезультатно.

Помогите.


PM MAIL   Вверх
marcusmae
Дата 14.3.2008, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Bladerender, похоже, что память съедают не фигурные скобочки, так что без кода парсера тут нечего сказать.


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Bladerender
Дата 19.3.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Код парсера возвращает коллекцию строк.
Тоесть класс, обьект которого возвращается имеет вид типа:

class Name
{
public string Name;
public List<string> collection = new List<string>();
}
PM MAIL   Вверх
marcusmae
Дата 19.3.2008, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Bladerender, вероятно, какая-то проблема с разделяемостью ресурсов или thread-safety. Кстати, вместо String-массива пользуйтесь StringBuilder, когда создаёте строку. Это - общие соображения. А конкретно я бы попробовал-таки разделить ресурсы, то есть либо сделать парсер статическим, либо создать его экземпляров по числу вычислительных потоков и поставить в Parallel.Do. С другой стороны покрутите и свой вариант - всегда же можно вместо некоторых кусков кода наставить временных заглушек и тем самым локализовать проблему.


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Bladerender
Дата 25.3.2008, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Делал статическим,  один перец. Нащет Parallel.Do, то пока не пробовал, но думаю что это все равно ничего не даст, так как потоки сами создают в Parallel.For по екземпляру на поток. Я в этьм почти уверен.
PM MAIL   Вверх
rubbiroid
Дата 26.3.2008, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 23.8.2006
Где: Германия

Репутация: нет
Всего: 1



Не знаю, может поможет. Если у тебя внутри потока есть цикл, в котором создаются объекты - то сборщик мусора "старые" объекты удалит только после выхода из цикла. У меня такое было на загрузке фоток - вплоть до вываливания в нехватку памяти (когда более 2 гигабайт съедало). Мне помогло собственноручное удаление объктов внутри цикла.

Это сообщение отредактировал(а) rubbiroid - 26.3.2008, 01:23
PM MAIL   Вверх
marcusmae
Дата 27.3.2008, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Bladerender

окей, я для примеру написал генератор строк

Код

using System;
using System.Text;

namespace StParGen
{
    public static class StringGenerator
    {
        /// <summary>
        /// The maximum 21 bit value. 
        /// </summary>
        const int bit21max = 0x10ffff;

        /// <summary>
        /// Generate random string of the specified length.
        /// </summary>
        /// <param name="length">The string length.</param>
        /// <returns>The resulting string.</returns>
        public static string GetString(int length)
        {
            StringBuilder stringBuilder = new StringBuilder(length);
            Random random = new Random();
            for (int index = 0; index < length; index++)
            {
                int randomNumber = random.Next(bit21max);
                while ((randomNumber >= 0x00d800) && (randomNumber <= 0x00dfff))
                    randomNumber = random.Next(bit21max);
                String subString = Char.ConvertFromUtf32(randomNumber);
                for (int subIndex = index; (subIndex < length) &&
                    (subIndex - index < subString.Length); subIndex++)
                    stringBuilder.Append(subString[subIndex - index]);
            }
            return stringBuilder.ToString();
        }
    }
}


и параллельно-последовательный тест с ним :

Код

using System;
using System.Threading;

namespace StParGen
{
    class Program
    {
        const int length = 1000, count = 10000;

        static void Main(string[] args)
        {
            SequentialRun();
            // ParallelRun();

            Console.WriteLine("Done.");
            Console.ReadKey();
        }

        static void SequentialRun()
        {
            string[] str = new string[count];
            for (int index = 0; index < count; index++)
                str[index] = StringGenerator.GetString(length);
        }

        static void ParallelRun()
        {
            string[] str = new string[count];
            Parallel.For(0, count, delegate(int index)
            {
                str[index] = StringGenerator.GetString(length);
            });
        }
    }
}


И ничего, апокалипсиса не наступило : в обоих случаях пик памяти - примерно 55 мб.

Я может, поскромничал, нужны более агрессивные условия? smile Давайте, в общем, сделаем пример таким, чтобы описанное поведение воспроизводилось.

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  StParGen.rar 23,81 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Bladerender
Дата 27.3.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Странно как-то получается. У меня Ваш код тоже работает нормально. Без апокалипсиса. Я разберусь что не так и вкину свой генератор.
PM MAIL   Вверх
marcusmae
Дата 27.3.2008, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Цитата(Bladerender @  27.3.2008,  17:53 Найти цитируемый пост)
вкину свой генератор


Зачем же сразу выкидывать?! = Дайте его потестить, что ли...


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1252 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.