JAVA Runtime Data Area의 세부 영역

infoqoch·2021년 1월 30일
0

JAVA

목록 보기
1/9

자바를 학습할 때 계속 막히는 부분이 있고, 무시하거나 암기를 하더라도 계속 나와 괴롭히는 부분이 있다. 바로 런타임을 학습할 때이다. 자바의 런타임에는 다양한 영역이 있고, 그 영역들이 관계를 맺으면서 메모리를 형성한다. 그런데 이에 대한 지식이 없는 상태에서, 중간 중간 마다 런타임에 대한 이해를 전제로 하는 내용이 나올 때마다, 해당 내용을 넘기거나 그냥 암기했다. 이제는 그러지 말자는 결심과 함게 런타임을 다시 정리하고 이해하고자 이 글을 작성한다.

런타임이란 자바언어가 .class파일로서 바이트코드로 컴파일된 값을 읽어내고 출력하는 환경을 의미한다. JVM이 런타임을 작동하는 주체가 된다.
런타임을 위해 호출되고 저장되고 출력되는 영역 중 이야기하고자 하는 영역은 Method, Heap, JVM Stack과 같다.

  1. JVM Stack area
  • 스택 영역은 스래드로서 작동한다. static main 매서드나 스레드의 선언 등으로 스택이 할당되고 생성되며, 해당 스레드가 종료되면 해당 스택 역시도 종료된다. 그러므로 관련한 변수는 해당 스레드의 생성과 종료에 종속된다.
  • 스택은 그것의 이름과 같이 메모리를 쌓는 형식으로 한다. int a = 3; 으로 선언을 했다가 그 다음에 a = 10;으로 하면 3은 사라지고 10이 덮어써진다. 이런 식으로 새로운 값(push)이 이전의 값을 밀어낸다(pop).
  • main 스레드에서 객체를 생성하고 메서드를 호출하며 스레드의 맴버 변수를 선언하는 등 다양한 작업 과정을 가진다. 그리고 해당 작업이 종료되면 더 이상 필요로 하지 않으므로 삭제된다.
  • 작업에 필요로하는 자원들, 그러니까 매서드, 필드값, 배열 등은 별도의 메모리에서 관리한다. 이는 이후에 이야기할 매소드 영역과 힙 영역이다.
  • 한편, 기본 타입(primitive data)은 스택 영역에서 바로 저장한다. 아무래도 기본 타입의 데이타 양이 크지 않고, 별도로 관리해야할 필요가 있을 정도의 복잡한 구조가 아니기 때문이라 생각한다. 반대로 참조 타입(reference type)은 참조할 대상의 주소를 가지고 있다. 주소가 가리키는 곳은 힙일 수도 있고 매서드일 수도 있다.
  1. Method area
  • 매소드 영역은 JVM이 시작할 때 생성되고 종료까지 사라지지 않으며 모든 스레드가 공유하는 영역이다. 클래스, 필드 데이터, 매소드 데이터, static, 생성자 등으로 선언된 맴버 변수와 매서드 등이 포함된다.
  1. Heap area
  • 객체와 배열이 생성되는 영역이다.

  • 더 이상 스택에서 필요로 하지 않는다고 판단하면, 쓰레기 수집기(Garbage Collector)가 삭제한다.

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

profile
JAVA web developer

0개의 댓글