티스토리 뷰

Java

Java 메모리구조(Heap, Stack)

개발도 운동만큼 2023. 3. 17. 00:46
반응형

필자는 Java가 가장 처음 배운 프로그래밍 언어였으며 메모리 구조에 대해 당연히 알아야 한다고 생각해서 이 글을 정리할려고 한다.

요즘은 Java -> Kotlin 회사 프로젝트를 많이 포팅하고 있기는 하지만 Kotlin 또한 Java 로 컴파일 되어 JVM 위에서 돌아가기 때문에 무조건 알아야 할 영역이다.

JAVA 의 메모리 구조

Class Path

  • 자바 가상머신(JVM)이 프로그램을 실행 할 떄, 클래스 파일을 찾는 데 기준이 되는 파일 경로, 즉 JVM이 클래스 파일을 찾는 경로.

  • bin 은 자바소스(.java 파일)가 컴파일 되어 새롭게 생성되는 .class 파일이 모여 있는 곳 이다.
    그것들이 모여 있는 위치가 'bin' 폴더

메모리 구조

  • JVM(자바 가상머신)이 실행되면 OS 가 JVM에게 필요한 메모리를 할당 해준다.

  • 컴퓨터 프로그램이 실행 되기 위해 필요한 메모리를 '메인 메모리' 라고 한다. 우리말로는 주기억장치, 물리족으로는 램(RAM)이라고 부르는 놈이다.

    이 RAM인 메인메모리를 관리하는게 OS 이고, JVM은 OS로 부터 필요한 만큼 할당을 받는다.

    OS로 부터 받은 메모리 공간을 RUntime Data Area 라고 하는데 이 ARea를 5개 영역으로 쪼개어 관리 한다.

Runtime Data Area

아래 5개의 목록으로 나누어 진다.

  • Class Area(=Method Area)
  • Stack Area
  • Heap Area
  • Native Method Stack Area
  • PC Register

image

image

메소드 영역(Class Area, Method Area)

  • 메소드 영역, 즉 여기는 클래스 파일의 바이트 코드가 로드되는 곳.

    JVM이 뭔가를 실행하려면 먼저 그 바이트코드 들이 메모리 공간에 저장이 되어야 한다.
    JVM은 메인 메소드를 호출하는 것으로 시작 한다, 거기서 부터 프로그램의 시작이라고 할 수 있다.
    우리가 메인메소드에서 사용하는 클래스와 static 변수가 메소드 영역에 올라온다.

    즉, 메소드 영역에 저장되는 바이트코드는 프로그램의 흐름을 구성하는 바이트코드 이다.
    이 바이트코드는 자바 컴파일러에 의해서 컴파일된 친구들이기 때문에, 사실상 전체 바이트코드가 이 영역에 올라간다고 봐도 무방하다.
    이렇게 메소드 영역에 바이트코드가 올라가는 것을 클래스 로딩 이라고 한다.
    이는 클래스를 사용하는 시점에 해당 클래스의 바이트코드가 들어있는 파일을 찾아서 메모리에 로딩하는 것을 말한다.

    클래스 로딩이 이뤄지는 이유
    메소드가 호출되려면, 먼저 그 메소드를 갖고 있는 클래스 파일이 메모리에 로딩이 되어 있어야한다.
    그래서 클래스를 실행할 때 *.class 파일을 찾아서 메모리에 로딩.

    클래스 로딩을 위한 JVM의 로딩 절차는 다음과 같다

    1. 어떤 메소드를 호출하는 문장을 만났는데, 그 메소드를 가진 클래스 바이트코드가 아직 로딩된 적이 없다면 곧바로 JVM은 JRE 라이브러리
      폴더에서 클래스를 찾음.
    2. 없으면, Classpath 환경변수에 지정된 폴더에서 클래스를 찾음.
    3. 찾았으면 그 클래스 파일이 올바른지 바이트코드를 검증.
    4. 올바른 바이트코드라면 메소드영역으로 파일을 로딩한다.
    5. 클래스 변수를 만들라는 명령어가 있으면 메소드 영역에 그 변수를 준비한다.
    6. 클래스 블록이 있으면 순서대로 그 블록을 실행한다.
    7. 이렇게 한번 클래스의 바이트코드가 로딩되면 JVM이 종료될때까지 유지된다.

아래 이미지는 쓰레드 스택에 저장된 지역변수들과 콜 스택, 그리고 힙에 저장된 객체들을 보여준다.

image

Stack Area

  • 흔히 말하는 call stack이 이 영역에서 다뤄지는 내용이다.
  • stack에서 선언된 지역변수는 stack에 위치한다.
  • primitive는 stack 영역에 저장되고 reference는 참조값만 저장된다.
  • 외부의 stack frame 에서는 내부 stack frame 변수 접근이 불가능하지만 내부에서 외부로는 가능하다.

Heap Area

  • 모든 쓰레드가 공유하며, new 키워드로 생선된 객체와 배열이 생성되는 영역이다.

  • 또한 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.

    PC Register

  • 쓰레드가 시작될 때 생성되며, 생성될 때 마다 생성되는 공간으로 쓰레드마다 하나씩 존재한다.

  • 쓰레드가 어떤 부분을 무슨 명령어로 실행해야할 지 에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.

    Native Method Stack

  • 자바외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함