자바를 학습할 때 계속 막히는 부분이 있고, 무시하거나 암기를 하더라도 계속 나와 괴롭히는 부분이 있다. 바로 런타임을 학습할 때이다. 자바의 런타임에는 다양한 영역이 있고, 그 영역들이 관계를 맺으면서 메모리를 형성한다. 그런데 이에 대한 지식이 없는 상태에서, 중간 중간 마다 런타임에 대한 이해를 전제로 하는 내용이 나올 때마다, 해당 내용을 넘기거나 그냥 암기했다. 이제는 그러지 말자는 결심과 함게 런타임을 다시 정리하고 이해하고자 이 글을 작성한다.
런타임이란 자바언어가 .class파일로서 바이트코드로 컴파일된 값을 읽어내고 출력하는 환경을 의미한다. JVM이 런타임을 작동하는 주체가 된다.
런타임을 위해 호출되고 저장되고 출력되는 영역 중 이야기하고자 하는 영역은 Method, Heap, JVM Stack과 같다.
객체와 배열이 생성되는 영역이다.
더 이상 스택에서 필요로 하지 않는다고 판단하면, 쓰레기 수집기(Garbage Collector)가 삭제한다.
(사실!) 위의 내용은 정확한 이해가 아닐 수도 있다. 언제나 실수를 용납하지 않는 엄밀한 이해는 인용으로부터 발생하는데, 인용을 하기에는 다소 딱딱하고 이해하기가 쉽지 않았다. 그래서 이래 저래 생각해보다가 조금 더 단순하게 런타임 영역을 이해해보고자 고민을 했고, 위와 같은 내용이 나왔다.
어디서 얼핏 들은 이야기 중 하나는 런타임은 일종의 작업 책상이란 비유이다. 만약 그런 식으로 가볍게 생각한다면, 컴파일이란 일종의 작업구상을 하고 필요한 자료와 책, 그리고 필요한 인력을 딱 모은 상태라고 볼 수 있을 것 같다.
작업이 실행되면(BootStrap) 그 과정에서 도구와 참고자료, 인력 등을 정리하고 꺼내서 Method Area에 넣는다(class load). 그리고 그러한 자원은 동시다발적으로 필요로 하는 영역에 투입하여 작업을 시키고(Thread), 그 영역의 작업이 종료되면 그것의 결과값만을 챙기고 나머지 작업했던 내용은 정리하면 된다(가비지 컬렉터의 힙 영역 정리, 스레드와 스택의 제거, 스레드의 종료).
스택을 좀 더 살펴보자면, 계산에 필요로 한 숫자는 종이에 쓰고 그냥 버리면 되겠지만(primitive data type), 망치나 계산기와 같은 도구는 공용 도구함(method area)에서 불러와서 사용하고, 단순한 숫자보다는 좀 더 양이 많은 것들은 노트로 정리하고 필요할 때마다 쓴다. 그런데 해당 작업 안에는 작은 작업들(frame)에 있을 것이고, 그때마다 망치나 계산기, 노트가 필요하진 않을 것이며, 또한 부피가 크기 때문에 작업대 앞에 늘어 놓으면, 작업이 불편할 것이다. 그러므로 옆에 공간에 보관 했다가 필요할 때마다 꺼내쓰면 될 것이다(new 연산자는 heap 영역을 할당할 때 사용한다. 그 값을 참조하여 필요할 때마다 다시 도구를 꺼내온다). 그리고 망치와 노트가 아예 필요 없다고 판단되면 정리하면 된다(heap영역의 삭제, 가비지 컬렉터).