Да, Строка. Разделение создает новый Строковый объект для каждой "части" - это - то, что это предназначено, чтобы сделать.
Теперь, примите во внимание, что строки в.NET являются Unicode (UTF-16 действительно), и с объектом наверху стоимость строки в байтах приблизительно 20 + 2*n
где n
количество символов.
Это означает, есть ли у Вас много маленьких строк, потребуется большая память по сравнению с размером текстовых включенных данных. Например, 80 символьных строк, разделенных на символьные строки 10 x 8, возьмут 80 байтов в файле, но 10 * (20 + 2*8) = 360 байтов в памяти - 4.5x взрыв!
Я сомневаюсь, что это - проблема GC - и я советовал бы Вам удалять дополнительные операторы, устанавливающие переменные в NULL, когда это не необходимо - просто проблема наличия слишком большого количества данных.
То, что я предложил бы, - то, что Вы читаете файл линию за линией (использование TextReader.ReadLine()
вместо TextReader.ReadToEnd()
). Очевидно наличие целого файла в памяти, если Вы не должны, расточительно.
Современные языки GC используют в своих интересах большой объем дешевой RAM для разгрузки memeory задач управления. Это налагает определенные издержки, но для Вашего типичного бизнес-приложения не действительно нужно так много информации так или иначе. Много программ обходятся меньше чем тысячей объектов. Вручную справление, что многие - тяжелая работа, bu даже тысячебайтовые издержки на объект, не имело бы значения.
В Вашем случае издержки на объект становятся проблемой. Можно, например, рассмотреть представление каждого столбца как один объект, реализованный с единственной Строкой и массивом целочисленных смещений. Для возврата единственного поля Вы возвращаете подстроку (возможно как контейнер)
Я предложил бы читать линию за линией вместо всего файла или блока до 1-2mb.
Обновление:
Из комментариев Jon я был любопытен и экспериментировал с 4 методами:
Чтение файла журнала 180 МБ:
Пользовательский StreamReader был:
StreamReader streamReader = new StreamReader(fileStream, Encoding.Default, false, 16384)
Буфер StreamReader по умолчанию 1024.
Для потребления памяти (фактический вопрос!) - ~800mb используемый. И метод, я даю все еще использованию StringBuilder (который использует строку), так никакое меньше потребления памяти.