несмежный объект String C # .net - PullRequest
0 голосов
/ 20 апреля 2010

Насколько я понимаю, объекты String и StringBuilder выделяют непрерывную память под ним.

Моя программа работает в течение нескольких дней, буферизуя несколько выходных данных в объекте String. Это иногда вызывает исключение из памяти, которое, я думаю, связано с отсутствием непрерывной памяти. мой размер строки может доходить до 100 МБ, и я часто конкатенирую новую строку, это приводит к выделению нового строкового объекта. я могу уменьшить создание новых строковых объектов с помощью Stringbuilder, но это не решило бы мою проблему полностью

Есть ли альтернатива смежному строковому объекту?

Ответы [ 6 ]

1 голос
/ 20 апреля 2010

НЕ ИСПОЛЬЗУЙТЕ СТРОКИ.

Строки будут копировать и выделять новую строку для каждой операции. То есть, если у вас есть строка 50 МБ и вы добавляете один символ, пока не произойдет сборка мусора, у вас будет две (приблизительно) строки 50 МБ. Затем вы добавляете еще один символ, у вас будет 3 .... и т. Д.

С другой стороны, правильное использование StringBuilder, то есть использование «Append», не должно иметь проблем с 100 МБ.

Еще одной оптимизацией является создание StringBuilder с вашим предполагаемым размером,

StringBuilder SB;

SB = новый StringBuilder (емкость); // в качестве емкости предложенный начальный размер

Используйте stringBuider для хранения вашей большой строки, а затем используйте append.

НТН

1 голос
/ 20 апреля 2010

При большом размере строки перемещаются в кучу больших объектов (LOH), и вы рискуете фрагментироваться.

Несколько вариантов:

  1. Использовать StringBuilder. Вы будете перераспределять реже. И попробуйте предварительно выделить, как new StringBuilder(100*1000*1000);

  2. измените дизайн вашего решения. Должны быть альтернативы хранению таких больших строк. Например, List<string>, который преобразуется только в одну строку, когда это действительно необходимо.

1 голос
/ 20 апреля 2010

A структура данных веревки может быть вариантом, но я не знаю ни одной готовой реализации для .NET.

Вы пытались использовать LinkedList строк вместо этого? Или, возможно, вы можете изменить свою архитектуру для чтения и записи файла на диск вместо того, чтобы хранить все в памяти.

0 голосов
/ 20 апреля 2010

Вы можете попробовать сохранить строку в базе данных, такой как TextFile, SQL Server Express, MySQL, MS Access, ... и т. Д. Таким образом, если ваш сервер отключится по какой-либо причине (отключение питания, кто-то столкнулся с ИБП, гроза и т. Д.), Вы не потеряете свои данные. Это немного медленнее, чем ОЗУ, но я думаю, что компромисс стоит того.

Если это не вариант - наиболее определенно используйте построитель строк для добавления строк.

0 голосов
/ 20 апреля 2010

Сначала вы должны изучить почему вы делаете это и посмотреть, есть ли другие вещи, которые вы можете сделать, которые дают вам такую ​​же ценность.

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

0 голосов
/ 20 апреля 2010

Я не верю, что есть какое-то решение для этого с использованием String или StringBuilder. Оба потребуют непрерывной памяти. Можно ли изменить вашу архитектуру так, чтобы вы могли сохранять текущие данные в список, файл, базу данных или другую структуру, предназначенную для таких целей?

...