В OP ваша программа прерывается, пока StringBuffer
расширяется. Вы должны предварительно распределить его по размеру, который вам нужен, или, по крайней мере, близко к нему. Когда StringBuffer
должен расширяться, ему требуется ОЗУ для исходной емкости и новой емкости. Как сказал TomTom, ваш файл, вероятно, содержит 8-битные символы, поэтому будет преобразован в 16-битный юникод в памяти, чтобы он удвоился в размере.
Программа еще даже не встречала следующего удвоения - то есть StringBuffer.toString()
в Java 6 выделит новый String
, а внутренний char[]
будет скопирован снова (в некоторых более ранних версиях Java это не было дело). Во время этой копии вам потребуется удвоить пространство кучи - поэтому в этот момент как минимум в 4 раза больше фактического размера файлов (30 МБ * 2 для байта-> Юникод, затем 60 МБ * 2 для вызова toString () = 120 МБ) , Как только этот метод будет завершен, GC очистит временные классы.
Если вы не можете увеличить пространство кучи для вашей программы, у вас возникнут некоторые трудности. Вы не можете выбрать «легкий» маршрут и просто вернуть String
. Вы можете делать это постепенно, чтобы вам не приходилось беспокоиться о размере файла (одно из лучших решений).
Посмотрите на код вашего веб-сервиса в клиенте. Он может обеспечить способ использования другого класса, отличного от String
- возможно, java.io.Reader
, java.lang.CharSequence
или специального интерфейса, например, связанного с SAX org.xml.sax.InputSource
. Каждый из них может быть использован для создания класса реализации, который читает из вашего файла порциями, когда это требуется вызывающим, вместо загрузки всего файла сразу.
Например, если маршруты обработки вашего веб-сервиса могут принимать CharSequence
, то (если они написаны правильно) вы можете создать специальный обработчик, который будет возвращать только один символ за раз из файла - но буферизует ввод. Смотрите этот похожий вопрос: Как бороться с большими строками и ограниченной памятью .