Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Переполнение Dictionary


Автор: N1ko 26.1.2011, 22:39
Здравствуйте, меня интересует, возможно ли как то избежать нехватки памяти в этом случае?  Записал это всё дело в текстовый документ - в результате он занял около 600 мб.
Когда же записываю в словарь - не доходит даже до 30000000 итерации и ругается на нехватку памяти. Dictionary забирает под себя все 4 гб оперативы, записав по сути всего метров 200 в себя. Как оказалось, он очень прожорлив. Попробовал с List - там дело обстоит гораздо лучше. Как я понимаю в словарях много памяти уходит на хэш
 
private void button1_Click(object sender, EventArgs e)
        {
            long i = 0;
            for (int d = 0; d < 50000000; d++)
            {
                string line = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
                dict.Add(i.ToString(), line);
                i++;
            }
        }

Зы Не спрашвайте зачем это нужно и не предлагайте использовать какую нибуть СУБД или что то подобное. Меня интересует конкретно этот случай.
За ранее всем благодарен.

Автор: Voyager 26.1.2011, 23:43
Нет.

Автор: wester 27.1.2011, 01:21
N1ko, 
загружать мелкими кусками и обрабатывать словарь нельзя ? 

если загружать мелкими порциями, то с течением времени CLR даст пинок сборщику мусору, и тот будет убирать неиспользуемые ссылки.
по крайней мере так думаю)

Автор: N1ko 27.1.2011, 01:46
Да не, меня как раз интересует загрузка целого куска данных и сразу. Пробовал я принудительно GC запускать, таймауты даже пробовал ставить (вот так извращался =)). Всё равно не помогает. 

Автор: jonie 27.1.2011, 08:39
Цитата(N1ko @  26.1.2011,  22:39 Найти цитируемый пост)
Dictionary забирает под себя все 4 гб оперативы,

не верю. в x86 в винде приложению доступно только два гига.

Цитата(N1ko @  26.1.2011,  22:39 Найти цитируемый пост)
Как оказалось, он очень прожорлив. Попробовал с List - там дело обстоит гораздо лучше.

ну вы и сравнили...


используйте x64, если не можете нормально алгоритм сделать обработки.

Автор: N1ko 27.1.2011, 12:48
Хм... А можно подробнее про алгоритм обработки? Можно сделать что то более эффективное в данном случае?
Поправка -  в винде x86 доступно почти 3.18 гб. Вот их все и заюзало. 

Автор: jonie 27.1.2011, 14:31
N1ko, 
Цитата(N1ko @  27.1.2011,  12:48 Найти цитируемый пост)
Поправка -  в винде x86 доступно почти 3.18 гб. Вот их все и заюзало. 

кто вам так безбожно наврал-то? Это еритики! Почитайте про устройство вирт памяти в винде (например в книжках по программированию драйверов). И "то что доступно самой винде" != "доступно моему приложению".

Цитата

Хм... А можно подробнее про алгоритм обработки? Можно сделать что то более эффективное в данном случае?
я не видел как вы обрабатываете данные. Ну если хочется то можно свой Dictionary сделать. Вплоть до unmanaged кода.

Автор: Экскалупатор 27.1.2011, 21:07
N1ko, а чем обусловлено то что данные нужно загружать все?

Автор: MefistoJ 28.1.2011, 15:29
Цитата(N1ko @ 26.1.2011,  22:39)
Здравствуйте, меня интересует, возможно ли как то избежать нехватки памяти в этом случае?  Записал это всё дело в текстовый документ - в результате он занял около 600 мб.
Когда же записываю в словарь - не доходит даже до 30000000 итерации и ругается на нехватку памяти. Dictionary забирает под себя все 4 гб оперативы, записав по сути всего метров 200 в себя. Как оказалось, он очень прожорлив. Попробовал с List - там дело обстоит гораздо лучше. Как я понимаю в словарях много памяти уходит на хэш
 
private void button1_Click(object sender, EventArgs e)
        {
            long i = 0;
            for (int d = 0; d < 50000000; d++)
            {
                string line = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
                dict.Add(i.ToString(), line);
                i++;
            }
        }

Зы Не спрашвайте зачем это нужно и не предлагайте использовать какую нибуть СУБД или что то подобное. Меня интересует конкретно этот случай.
За ранее всем благодарен.

В словаре не может находиться элементов больше чем Int32.MaxValue.Конструктор словаря Dictionary<Key , Value>(int capacity).Так что в один словарь видимо не запихнеш) 

Автор: N1ko 28.1.2011, 15:36
int.MaxValue = 2147483647  гораздо больше чем 50000000


Автор: wester 28.1.2011, 23:03
N1ko, 
попробуй это http://msdn.microsoft.com/ru-ru/library/system.collections.specialized.stringdictionary.aspx

Автор: m0nax 31.1.2011, 02:39
Код

            Dictionary<int, string> dict = new Dictionary<int, string>(50000000);
            int i = 0;
            const string line = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

            for (int d = 0; d < 50000000; d++)
            {
                dict.Add(i, line);
                i++;
            }

            button2.Text = "ok";

Кроме того что выполняется почти моментально, прекрасно умещается в памяти

Только не надо говорить "а я так не хочу" - не хочешь оптимизировать код, но хочешь чтоб все было быстро и хорошо? 
Ну бред же чеслово...

Автор: Экскалупатор 31.1.2011, 11:15
m0nax, о какой оптимизации ты говоришь? у меня падает исключение о нехватке памяти на первой строке
Код

Dictionary<int, string> dict = new Dictionary<int, string>(50000000);

очевидно двух гигов все же не хватает...

Автор: m0nax 31.1.2011, 15:53
Экскалупатор, ну у меня самого 2.5 гига, на выполнение хватило всего одного
А вариант из первого поста вываливался с исключением про нехватку памяти...

В любом случае тут ключевой момент в  new Dictionary<int, string>(50000000);
Без этого словарю приходится выделать память под новые элементы по мере их добавления и копировать туда существующие данные(а старая память становится мусором)

Автор: Экскалупатор 31.1.2011, 16:18
m0nax, это понятно. но памяти при этом тоже не хватает. да и к тому же тут есть небольшая нестыковка. в первом посте сказано что строки читаются из файла, а по сему их будет не одна(как в твоем примере) а 50000000. так что это очевидно не спасет.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)