티스토리 뷰

Java

자바(JVM)의 메모리 사용 방식 (T 메모리 구조)

사용자 siyoon210 2019. 2. 21. 19:39
반응형

자바(JVM)의 메모리 사용 방식

프로그램을 실행시킬 때 CPU와 조화로운(?) 작업을 위해서 저장장치에 있던 내용들이 메모리에 올리가기 시작합니다. 메모리에 데이터들이 어떤 방식으로 올라가는지 이해하는 것은 더 나은 개발자가 되기 위한 필수 과정이라고 생각합니다. 메모리 구조를 알게 된다면, 클래스 멤버, GC(가비지 컬렉터), 쓰레드가 어떤식으로 독립적으로 운영되면서 공유하는 자원이 있는지에 대한 이해를 훨씬 더 쉽고 깊게 알 수 있습니다.


메모리는 크게 4가지 영역으로 나눌 수 있습니다. 로우레벨 개발자가 아니라면 주로 우측에 static 영역, stack 영역, heap 영역을 위주로 알고 있으면 됩니다. 이 세가지 영역을 간단히 T메모리라고 부르겠습니다.

static 영역

  • 패키지나 클래스 정보가 올라갑니다. 
  • 패키지나 클래스는 프로그램 시작과 동시에 모두 올라가는 것이 아니라, 실제로 호출 될 때 올라가게 됩니다. (JVM은 영리합니다.)
  • static이라는 키워드를 붙여서 선언된 필드와 메소드인 '클래스 멤버'도 static 영역에 올라갑니다. static 영역에 있는 것은 어떤 곳에서나 접근이 가능해지기 떄문에 '전역'이라는 키워드를 사용합니다.
  • 그러므로, static (전역) 변수는 읽기 전용이 아닌 경우에는 가능한 사용하지 말아야 합니다. (누구나 접근해서 값을 수정하면 혼란을 가져 올 수 있기 때문)
  • class영역 혹은 method 영역 이라고도 불립니다.
  • static 영역에 자리잡게되면 JVM이 종료 될 때까지 사라지지 않고, 고정된(static) 상태로 유지됩니다.

stack 영역

  • 여는 중괄호 '{'를 만날 때 마다 스택 프레임이 하나씩 생기고, 닫는 중괄호 '}'를 만나게 되면 스택 프레임이 사라집니다. 그러므로 메소드가 실행될 뿐 만 아니라, if문, 반복문, 예외처리를 위한 try문 등도 모두 스택프레임이 생기게 됩니다.
  • stack 내부에서 선언된 지역변수는 stack 영역에 올라갑니다.
  • 기본형 타입 변수의 값들은 stack영역에 저장되고, 참조형 타입 변수는 참조값만 저장됩니다. (이 참조값은 heap 영역에 존재하는 인스턴스(객체)를 가르키는 역할을 합니다. 엄격한 표현은 아니지만 인스턴스(객체) 주소값 정도로 이해하셔도 됩니다.)
  • 외부 스택 프레임에서는 내부 스택 프레임의 변수에 접근 하는 것은 불가능하나 그 역은 가능합니다. 쉽게 생각하면 메소드안에 for문 스택 프레임을 만든 경우, for문에서는 자신을 호출한 메소드의 변수는 사용가능하나, 메소드에서는 for문에서 선언한 변수를 사용 할 수 없습니다. 
  • + 메소드를 호출하는 것은 별개의 스택프레임 이기 때문에 스택 프레임을 넘어서 접근할 수 없습니다.
  • 쓰레드도 stack 영역에 생기게 됩니다. 하나의 쓰레드는 내부적으로 별개의 T메모리 구조 static, stack, heap영역을 갖게 됩니다. 이런 이유로 하나의 쓰레드는 다른 쓰레드로 접근 할 수 없지만, static 영역과 heap 영역은 공유해서 사용 할 수있는 특징을 가지게 됩니다. (이런 특징이 멀티 프로레스 구조보다 멀티 쓰레드 구조가 메모리를 적게 사용 할 수 있는 이유입니다.)

heap 영역

  • 생성된 객체(인스턴스)들이 올라갑니다.
  • 인스턴스 필드들은 heap 영역에 올라갑니다. (이러한 이유로 static한 메소드에서 인스턴스 멤버를 접근할 수가 없는 겁니다. 어떤 인스턴스 인지도 알 수 없고, 존재하지도 않을 수도 있는 인스턴스를 사용하라는 것이기 떄문입니다.)
  • 메소드들은 static이 아니더라도 굳이 heap에 생기지 않습니다. 어차피 같은 로직의 메소드이기 때문에, 여러개 일 필요가 없습니다. (JVM은 영리합니다.)
  • stack영역에서 참조값을 이용하여 참조형 변수가 heap 영역에 있는 인스턴스를 가르키어 제어 할 수 있게 됩니다.
  • 어떤 참조 변수도 힙영역에 있는 인스턴스를 참조하지 않게 된다면, GC(가비지 컬렉터)에 의해 메모리에서 사라지게 됩니다.
  • 상속을 이용한 인스턴스를 만들었다면 상위 클래스들의 인스턴스들도 같이 생성됩니다. (최상위인 Object까지)

참고도서 - 스프링 입문을 위한 자바 객체지향의 원리와 이해 (김종민 저자)

반응형
댓글
댓글쓰기 폼