참고 : http://stackoverflow.com/questions/20030120/java-default-stack-size , http://stackoverflow.com/questions/10481528/in-java-which-objects-are-put-on-the-stack-and-which-on-the-heap , http://stackoverflow.com/questions/6366211/what-are-the-roots
JVM의 VM 옵션의 -XX옵션 중에 ThreadStackSize라는 스택의 크기를 지정할 수 있는 옵션이 있다(JRockit의 경우 -Xss). JVM은 Java 메소드 호출 정보와 Native 메소드 호출 정보를 저장할 장소가 필요한데 JVM에 따라 둘을 한 스택 프레임에서 관리하는 경우도 있고 분리해서 관리하는 경우도 있다. 따라서 여기서 지칭하는 스택은 자바에서 각각의 쓰레드(thread)별로 최소 1개 이상 할당되는 저장소를 가리킨다.
스택의 기본 크기는 플렛폼에 따라 다르며 신규 쓰레드가 생성되면 정해진 스택사이즈의 메모리 공간이 힙(heap)과는 별도의 공간을 이용하여 각각의 쓰레드에 할당되게 되는 것이다.
-XX:ThreadStackSize=512 | Thread Stack Size (in Kbytes). (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.] |
쓰레드에 할당된 스택에는 지역변수, 파라메터, 반환주소 등을 기억하며 일반적으로 객체는 저장되지 않으며 참조 주소만 기억하게 된다. 이와 같은 특성을 가지고 있기 때문에 스택에 저장되는 원시타입(primitive type) 데이터가 많다면 array와 같은 컬렉션 객체로 관리하게 되면 스택에 저장되는 데이터의 사이즈를 줄일 수 있을 것이다.
이와 관련하여 예외가 존재하긴 하는데 그럴 경우 장점은 스택은 캐쉬될 가능성이 높기 때문에 지역변수에 대해 캐시의 지역성을 높여 접근시간을 줄이고 힙에서 관리할 데이터를 줄여 가비지 컬렉터(gargabe collector)를 덜 바쁘게 하는 효과와 싱글 쓰레드 액세스가 보장되기 때문에 쓰레드 잠김(locking)과 관련한 체크가 필요없어지는 장점을 얻을 수 있다고 한다. 그밖에 참고할 만한 자료로 상단 링크의 Escape Analysis 항목이 도움이 될 것이다.(일단 글의 주제는 스택 사이즈이다보니..-_-;;)
스택의 크기 설정과 관련해서 발생할 수 있는 문제가 몇가지 있는데 만약 스택의 크기를 크게 잡았을 때 쓰레드가 기하급수적으로 늘어난다면 OutOfMemory 오류를 접할 수 있을 것이고 반대로 너무 작게 잡은 상태라면 쓰레드에서 기억해야 하는 데이터의 크기보다 스택의 크기가 작아 StackOverFlow 오류를 보게될 수 있다.
마지막으로 사용된 스택 프레임은 해당 쓰레드가 종료되면 자동으로 제거 되게 될 것이다..