Чтение строк из текстового / сцинтилляционного блока .NET без использования слишком большого количества памяти? - PullRequest
0 голосов
/ 04 июня 2010

Мне нужно создать программу на C #, которая хорошо справляется с чтением огромных файлов.

Например, у меня есть файл размером более 60 МБ. Я прочитал все это в коробку сцинтиллы, давайте назовем это sci_log. Программа использует примерно 200 МБ памяти с этой и другими функциями. Это все еще приемлемо (и меньше, чем объем памяти, используемый Notepad ++ для открытия этого файла).

У меня есть еще одна коробка для сцинтиллы, sci_splice. Пользователь вводит поисковый термин, и программа ищет файл (или sci_log, если длина файла достаточно мала - это не имеет значения, потому что это происходит в обоих направлениях), чтобы найти regexp.match. Когда он находит совпадение, он объединяет эту строку со строкой, которая имеет предыдущие совпадения, и увеличивает временную переменную count. Когда count равен 100 (или 150, или 200, на самом деле любое число), тогда я помещаю вывод в sci_splice, вызываю GC.Collect () и повторяю для следующих 100 строк (установка count = 0, обнуление строки).

У меня нет кода сейчас, когда я пишу это со своего домашнего ноутбука, но проблема в том, что он использует МНОГО памяти. Использование 200 мегабайт памяти увеличивается до 1 гб без конца. Это происходит только при поиске с большим количеством совпадений регулярных выражений, так что это что-то со строкой. Но проблема в том, не освободит ли ГК эту память? Кроме того, почему он поднимается так высоко? Не имеет смысла, почему это более чем в три раза (наихудший возможный случай). Даже если все эти 200 МБ были просто журналом в памяти, все, что он делает - читает каждую строку и сохраняет ее (в худшем случае).

После еще одного тестирования похоже, что что-то не так со Scintilla, использующим много памяти при добавлении строк. Первоначальное чтение строк имеет скачок памяти до 850 мБ за доли секунды. Думаю, мне нужно просто просмотреть страницу вывода.

Ответы [ 3 ]

0 голосов
/ 04 июня 2010

Не звоните в GC.Collect.В этом случае я не думаю, что это имеет значение, потому что я думаю, что эта память окажется в куче больших объектов (LOH).Но дело в том .Net знает гораздо больше об управлении памятью, чем вы;оставьте это в покое.

Я подозреваю, что вы смотрите на это с помощью диспетчера задач так, как вы его описываете.Вместо этого вам нужно использовать хотя бы Perfmon.Предвидя, что вы не использовали его до , идите сюда и делайте то, что делает Тесс там, где написано «Получить дамп памяти».Не уверен, что вы готовы к WinDbg, но, возможно, это ваш следующий шаг.

Без просмотра кода почти невозможно узнать, что происходит.Проблема может быть и внутри Scintilla, но я бы проверил, что вы делаете в первую очередь.Запустив perfmon, вы можете по крайней мере получить больше информации, чтобы выяснить, что делать дальше.

0 голосов
/ 04 июня 2010
0 голосов
/ 04 июня 2010

Если вы используете System.String для хранения совпадающих строк, я предлагаю вам попробовать заменить его на System.Text.StringBuilder и посмотреть, имеет ли это значение

...