Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Ошибка Out of memory при загрузке файла в TStringList


Pcrepair ©   (13.12.17 23:14

Добрый день. Есть следующая ситуация
РС(i7 8Gb Win7 x64 + RAD XE3), приложения можно компилировать только в 32 разр. режиме
- список грузит файл с диска

Procedure RestorData;
begin
 try
   CS.Enter;
   try
     gStore.LoadFromFile(ExtractFilePath(Application.ExeName)+'Store.txt');
   finally
     CS.Leave;
   end;
 except
   on E:Exception do
   begin
     ShowMessage('RestorDataParams = '+'('+E.Message+')');
   end;
 end;
end;

- при определенных условиях(не всегда) выскакивает ошибка:
First chance exception at $7561C54F. Exception class EOutOfMemory with message 'Out of memory'. Process loader.exe (3736)
в основном ошибка выскакивает при попытке загрузить в список файл размером в 300 мб с числом строк около 3 млн. при запуске программы,
или выгрузить список обратно при выходе из программы.
- список со строками совершенно необходим(стек со списком УРЛ для загрузки), хотя...

Вопросы :
1. вообще эта проблема решаема для TStringList
2. если список не тянет, что еще можно использовать для загрузки-выгрузки милионов строк(до 500 символов в строке) из какого либо хранилища на ЖД


kilkennycat ©   (14.12.17 10:44[1]

1. да.
2. TStringList

TStringList служит для отображения. отобразить он может лишь столько, сколько мониторов у компа. Остальное храните там, где оно уже хранится.


Pcrepair ©   (14.12.17 10:52[2]

с листбокс не перепутал? для отображения ахаха


KilkennyCat ©   (14.12.17 11:08[3]

нет, перепутал с вариантом ответить или нет. надо было не отвечать.


Sha ©   (14.12.17 12:37[4]

> список со строками совершенно необходим(стек со списком УРЛ для загрузки)

Предполагается ли затем все эти УРЛ также одновременно загрузить?
Просто вопрос.


han_malign ©   (14.12.17 12:54[5]


> (стек со списком УРЛ для загрузки)

- при условии последовательного доступа к элементам списка - проще хранить единым блоком с строке и парсить на лету...
Либо отдельно построить список смещений. Либо честный связный список...

Проблема древняя как мир
LoadFromFile():
1. Файл целиком загружается в строку.
2. SetTextStr()
- где на каждом элементе происходит выделение памяти под очередную подстроку и перевыделение памяти под очередной размер списка.
То есть на определённом этапе у нас
- выделена память под все содержимое файла
- выделена память под N-подстрок
- выделена память под array[N] of TStringItem
а нам надо выделить память под array[N+N div 4] of TStringItem, т. к. N-подстрок с большой долей вероятности фрагментируют память - и расширение блока памяти на месте невозможно.
(...|array[n]|...substr[N-1]|)

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

Если заранее знать количество строк - проблему можно временно решить
gStore.Capacity:= MaxN;
- если (<размер фала> * 2 + O(N) + MaxN * sizeof(TStringItem)) - не вылезает за размер доступной памяти.
O(N) - оверхэд на хранение N строк(TStrRec + списки менеджера памяти).


> для загрузки-выгрузки

TMemoryStream.LoadFromFile();
parse_and_do_something(PChar(TMemoryStream.Memory), TMemoryStream.Size);


Pcrepair ©   (14.12.17 16:15[6]


> Предполагается ли затем все эти УРЛ также одновременно загрузить?

предполагается, но не одновременно а поочередно, причем выборка текущего УРЛ через РандомРеиндж

пока что использование АссасинФайл вполне помогло в деле загрузки 3млн. строк из текстового файла в переменную(список). правда грузится подольше, но это не принципиально


Sha ©   (14.12.17 21:19[7]

В таком случае непонятно, зачем грузить строки.

Можно держать их в любой БД или сортированном файле.


han_malign ©   (15.12.17 08:49[8]


>  или сортированном файле

- проблема не в сортировке, а в равномерном распределении РандомРеиндж по элементам. Если делать случайную выборку по полному размеру файла - вероятность попадания будет зависеть от длины URL(в сравненнии с количеством элементов - перекос мизерный, но лучше избегать математических ловушек, т.к. если отсортировать элементы по длине - получим явно выраженную линейную функцию распределения)... То есть, нужно либо нормализовать длину строки, либо строить индекс смещений. Если нужна выборка с отсечением дублей - однозначно индекс, который можно рэндомизировать при построении, а потом делать прямой обход.
З.Ы. Главное не удивляться, что случайный список всегда получется одинаковый, при одинаковом начальном RandSeed. :)

>  держать их в любой БД

- я так полагаю - список URL быстро устаревает, и скорее всего периодически генерируется какой-то третьей стороной в самом элементарном виде, и БД превратится в run-time прослойку(тот самый микроскоп)...
Хотя уже замечал тенденцию использовать LiteSQL в роли универсального контейнера...


Sha ©   (15.12.17 09:40[9]

> проблема не в сортировке, а в равномерном распределении РандомРеиндж

я даже не догадываюсь, что такое этот ваш РандомРеиндж,
но если это то, что я думаю, то можно отсортировать по нему
и просто читать файл последовательно-закольцовано ))


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо