안경잡이개발자

728x90
반응형

  Java로 간단한 프로그램을 작성하여 실행했다. 다만 동일한 함수를 30만 번 재귀적으로 호출했더니 다음과 같이 Stack Overflow Error가 발생했다. 오류는 일반적으로 다음과 같이 "java.lang.StackOverflowError" 형태로 출력되는 것을 알 수 있다. 기본적으로 30만 번 정도의 호출은 감당할 수 있을 정도로 기본적인 Stack Size를 키우고 싶다면 어떻게 해야 할까? 참고로 Heap 관련 오류로는 "java.lang.OutOfMemoryError: Java heap space" 등의 오류가 있다.

 

 

※ JVM 기본 플래그(flag) 값 확인 ※

 

  명령 프롬프트(CMD)를 실행한 뒤에 다음과 같은 명령어를 입력한다. 그러면 Stack이나 Heap이라는 문자열이 포함된 플래그(flag)를 확인할 수 있다.

 

java -XX:+PrintFlagsFinal -version | findstr "Stack Heap"

 

  명령어 실행 결과 예시는 다음과 같다. 일반적으로 Stack 크기와 관련해서는 ThreadStackSize를 확인한다.

 

 

  다만 필자처럼 윈도우(Windows) 운영체제를 사용하는 경우 ThreadStackSize 값이 0으로 나오는 문제가 있다. 기본적으로 Windows에서는 ThreadStackSize의 값이 가상 메모리에 따라서 다르게 적용된다고 알려져 있다. 그래서 Xss 옵션으로 Stack Size를 변경한다고 해도, 이것이 실제로 기본값보다 크게 만드는 것인지 혹은 작게 만드는 것인지 확실치 않았다. 그래서 필자의 경우에는 여러 번 시도해 보면서 적절한 크기를 찾았다. Stack Size와 관련하여 오라클(Oracle)에서 제공하는 참고 문서는 다음과 같다.

 

  참고: https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp1024112

 

  JVM의 옵션(option)-X{option} 형태로 적용할 수 있다. 예를 들어 java -Xss1m은 각 쓰레드(thread)에 할당되는 최대 스택 크기를 1m로 설정하기 위해 사용할 수 있다. 기본적으로 각 쓰레드(thread)에는 하나 이상의 스택이 존재한다. 따라서 필자가 현재 경험한 문제의 경우 Xss256m이나 Xss512m 옵션으로 문제를 해결할 수 있는 것이다. 아무튼 Main 클래스(class)를 -Xss256m 옵션과 함께 실행하기 위해서는 다음과 같이 입력할 수 있다.

 

java -Xss256m Main.java

 

  혹은 애초에 다음과 같이 튜닝 플래그를 사용하여 다음과 같은 방식으로 스택 크기를 설정할 수도 있다. 

 

java -XX:ThreadStackSize=1m Main.java

 

  참고로 특정한 JVM의 경우 최솟값보다 작은 크기로 설정하는 것을 허용하지 않기도 한다. 예를 들어 다음과 같이 Stack Size를 1k로 설정하려고 하면, 최소한 180k 이상의 Stack Size를 가져야한다고 나오는 것을 알 수 있다.

 

 

  아무튼, 결과적으로 다음과 같이 실행하여 Stack Overflow 발생 없이 프로그램을 실행할 수 있었다.

 

java -Xss256m Main.java
728x90
반응형

Comment +0