Принципиально, JLS 15.12.4.5 требует бросить SOE, если не хватает памяти для записей активации. Так что с точностью до багов в JVM можно ожидать, что бесконечно рекурсивный метод в отсутствие трюков c tailrec должен бросить SOE. Думаю, что даже в JCK такой тест есть...
про OOME я могу себе представить как ломается JVM 🙂 а если SOE которое я сам себе создал на текущем треде при помощи одной функции и тут же его поймал - я не могу себе представить как я могу сломать JVM таким тонким искуственным способом вызвать SOE - буду очень благодарен если есть что-то почитать на эту тему или еще лучше существующие тесты JDK с похожими трюками и где не выбрасывают JVM после SOE
Да, упомянутый JEP 270 описывает, пожалуй, единственную важную проблему с этим. Но нужно заметить, что это ломание не в JVM, а в пользовательском коде, внезапно получившему системное исключение в критическом куске своего кода.
у меня основная идея теста в том что на большом количестве повторений чего-то не вылетает SOE (поэтому я не хочу бесконечно вызывать функцию ибо тест упадет - а вызываю SOE я исключительно для того чтоб проверить текущие настройки JVM чтоб знать что тест реально что-то тестит (если это вообще возможно конечно - может быть я не правильно понимаю что-то в JVM и глупость затеял)
Саму JVM этим не сломаешь: ну поймаете SOE, попытаетесь в обработчике что-нибудь сделать, поймаете ещё один SOE. Структурно обработчики ациклические, так что в определённый момент SOE будет хэндлить некому, и тред выйдет вон.
В этом месте надо на происходящее в байткоде и скомпилированном коде смотреть. Можно случайно на tailrec-like оптимизацию наступить, особенно на пустых методах, и привет. JLS говорит, что SOE кидают, когда место для новых фреймов заканчивается, а новых фреймов может и нет :)
def triggerStackOverflowError(n: Int): Int = { if (n <= 0) n else n + triggerStackOverflowError(n - 1) } val stackOverflowErrorDepth = 1000000 // check that deep enough recursion results in StackOverflowError with current JVM settings try { // trigger SOE with given stackOverflowErrorDepth triggerStackOverflowError(stackOverflowErrorDepth) fail( s"expected a StackOverflowError from $stackOverflowErrorDepth-deep recursion, consider increasing the depth in test" ) } catch { case _: StackOverflowError => // stackOverflowErrorDepth has correct value }