2016-03-16 2 views
0

Я использую Nashorn на 1.8u60 для создания объектов модели, чтобы вернуться к виду уровня (тимелеаф). Часть объекта модели представляет собой несколько большую строку (не достаточно большую, чтобы вызвать какие-либо проблемы в простой Java), содержащие HTML. При попытке преобразовать объект обратно в Java с помощью методов ScriptObjectMirror я получаю следующее исключение. Изменение размера максимальной кучи не оказывает никакого влияния (изменено с 900 МБ до 1800 МБ, такая же ошибка). Я не мог найти много онлайн об этом, но существуют ли какие-либо ограничения, которые Nashorn налагает на размеры объектов? Я собираюсь попробовать последние 1,8 JDK.Nashorn OutOfMemoryError при создании больших объектов js (строки)

java.lang.OutOfMemoryError: Java heap space 
    at jdk.nashorn.internal.runtime.ConsString.flatten(ConsString.java:105) 
    at jdk.nashorn.internal.runtime.ConsString.flattened(ConsString.java:98) 
    at jdk.nashorn.internal.runtime.ConsString.toString(ConsString.java:69) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.wrap(ScriptObjectMirror.java:704) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.wrapLikeMe(ScriptObjectMirror.java:721) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.wrapLikeMe(ScriptObjectMirror.java:730) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.access$300(ScriptObjectMirror.java:64) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror$13.call(ScriptObjectMirror.java:371) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror$13.call(ScriptObjectMirror.java:364) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.inGlobal(ScriptObjectMirror.java:859) 
    at jdk.nashorn.api.scripting.ScriptObjectMirror.entrySet(ScriptObjectMirror.java:364) 

...

Спасибо, Адриан

+0

Пожалуйста, добавьте фрагмент кода – Nayan

ответ

1

Эта линия читает

 final char[] chars = new char[length]; 

так кажется, что есть на самом деле не хватает памяти для конечной строки. Nashorn использует ConsString как способ амортизации затрат на конкатенацию, задерживая конкатенацию до тех пор, пока результат не будет использован (большинство JS-движков используют эту оптимизацию, иначе, например, для конкатенирования множества строк в цикле потребуется время O (n^2)).

Это означает, что у вас может быть результат многих операторов + на строках - это дерево объектов ConsString, которые сразу же «сплющиваются». Компромисс для линеаризации времени конкатенации - это необходимость держать вокруг них ConsStrings, для чего требуется более чем вдвое больше памяти, необходимой для строки (более чем в два раза - для собственных объектов ConsString).

Один из способов обойти это - периодически вызывать str.toString(). Это, по-видимому, не-op, но внутренне оно приводит к выравниванию дерева конкатенации. Попробуйте ввести его в свой код в какой-то момент и посмотреть, помогает ли он.

+0

Спасибо Attila. Это помогло, и это также привело меня к ошибке, которая приводила к тому, что строка была намного больше, чем я думал. Сейчас все хорошо. – adrian

Смежные вопросы