Вопрос, что делает состояние 1 MB размера стека в JVM, как я понятия не имею, что размер стек кадр?
Размер стека по умолчанию в 1 МБ означает, что каждый поток имеет 1 МБ (1048576 байт) пространства стека ... по умолчанию. Исключением является, если ваш код создает поток, используя один из конструкторов Thread
, где вы можете предоставить аргумент размера стека.
Размер фрейма стека зависит от вызываемого метода. Он должен содержать параметры метода и локальные переменные, поэтому размер кадра зависит от их размера.Для каждого кадра также требуется (я думаю) два дополнительных слова для хранения сохраненного указателя кадра и сохраненного обратного адреса.
Обратите внимание, что в рекурсивном алгоритме у вас может быть несколько кадров стека для одного «уровня рекурсии». Для writeObject
(в Java 8), алгоритм, используемый рекурсивно, и, как правило, 4 кадра в уровне структуры данных сериализации:
writeObject0
writeOrdinaryObject
writeSerialData
defaultWriteFields
writeObject0
etcetera
Фактические размеры кадров будет зависеть платформа из-за различий в трансляторов, и изменения в реализации ObjectInputStream/ObjectOutputStream. Вам лучше попытаться (грубо) измерить требуемое пространство стека, а не пытаться предсказать размеры кадров с первых принципов.
Еще один вопрос, имеет ли каждый поток размер стека 3000k, если я ставлю JVM-параметр -Xss3000k?
Да ... за исключением того, что я описал выше.
Одним из возможных решений вашей дилеммы является создание специального потока с огромным стеком, который вы используете для сериализации. Для десериализации потребуется подобный поток с огромным стеклом. Для остальных потоков размер стека по умолчанию должен быть точным.
Другие возможные решения:
Реализовать writeReplace
и readResolve
методы для выравнивания родительской структуры ваших объектов ЕРС в массив, так что вы не получите глубокую рекурсию. (Очевидно, что уплощение/unflattening должно быть сделано нерекурсивно.)
Сделайте то же самое уплощение перед тем вы звоните writeObject
, и так далее.
Используйте другой механизм сериализации или пользовательский.
Не могли бы вы рассказать о том, «что делает размер стека 1 МБ в JVM», это не очень понятно. –
Этот код не похож, он должен потреблять много пространства стека. Как работает 'getParent()'? «Сериализовать объект» означает «записать его в ObjectOutputStream»? – Thilo
@ RazvanManolescu Я хотел знать, может ли 1 MB обрабатывать сериализацию объекта с родительской иерархией из 3022 родителей? –