Ответ 1
Для каждого символа требуется 2 байта (в качестве char
в .NET - код кода UTF-16). Таким образом, к тому времени, когда вы достигли 800 миллионов символов, требуется 1,6 ГБ непрерывной памяти 1. Теперь, когда StringBuilder нуждается в изменении размера, он должен создать другой массив нового размера (который, как я полагаю, пытается удвоить емкость), что означает попытку выделить массив 3,2 ГБ.
Я считаю, что CLR (даже в 64-битных системах) не может выделить один объект размером более 2 ГБ. (Это, конечно, имело место.) Я предполагаю, что ваш StringBuilder
пытается удвоить размер и сдуть этот предел. Возможно, вы сможете получить немного больше, построив StringBuilder
с определенной пропускной способностью - возможно, будет возможно около миллиарда.
В нормальном ходу вещей это не проблема, конечно - даже строки, требующие сотни мегабайт, редки.
1 Я полагаю, что реализация StringBuilder
фактически изменилась в .NET 4, чтобы использовать фрагменты в некоторых ситуациях, но я не знаю деталей. Таким образом, он может не всегда нуждаться в непрерывной памяти, но все еще в форме строителя... но это было бы, если бы вы когда-либо звонили ToString
.