자바 메모리 구조(1)

wnajsldkf·2022년 10월 2일
0

Java

목록 보기
7/19
post-thumbnail

JAVA의 Static 개념을 공부하다가 메모리라는 단어를 여러번 마주하였다. 자바의 메모리는 어떤 것을 말하는 것일지 궁금해 공부를 시작한다.

자바의 실행 과정

우리는 리눅스 환경에서 개발한 자바 프로그램을 윈도우에서 실행하는 것처럼 운영체제 상관없이 프로그램을 실행할 수 있다. 이는 자바 프로그램을 실행할 때 자바 언어와 이를 실행하는 운영체제 사이를 연결하는 JVM이 존재하기 때문이다. 그럼 자바 프로그램은 어떻게 실행될까?

  1. JVM은 OS로부터 프로그램이 필요로하는 메모리를 할당받는다. JVM은 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
  2. 자바 컴파일러는 자바 코드를 바이트 코드로 변환시킨다.
    • 바이트 코드는 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법을 말한다. 즉, 자바 바이트 코드는 자바 언어로 작성한 코드를 JVM이 이해할 수 있는 것으로 바꾼 것이다.
  3. Class Loader를 통해 class 파일을 JVM으로 로딩한다.
    • Class Loader는 자바의 동적 로드(런타임(= 바이트 코드 실행 시)에 클래스를 로드 및 링크)를 담당한다. 이는 한 번에 메모리에 모든 클래스를 로드하는 것이 아닌, 필요한 순간에 해당 클래스(.class) 파일을 찾아 메모리에 로딩한다.
  4. 로딩된 class 파일들을 Execution Engine을 통해 해석한다.
    • Execution Engine은 바이트코드를 명령어 단위로 해석한다. 실행 방식에는 Interpreter 방식, JIT(Just In Time) 컴파일 방식 또는 동적 번역(Dynamic Translation)이 있다.
  5. 해석된 바이트코드를 Runtime Data Area에 배치하여 수행이 이루어진다.
    • Runtime Data Area는 JVM이 프로그램을 수행하기 위해 OS로부터 할당받는 메모리영역이다.

JVM이란?

그럼 JVM은 어떤 역할은 하는 것일까?

JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 용도에 따라 여러 영역으로 나누어 관리한다. JVM 영역은 다음 그림처럼 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack으로 구분된다. 각각의 영역은 어떤 역할을 하는 것일까?

그림과 같이 PC Register, JVM Stack, Native Method Stack 영역은 Thread별로 생성되고 Heap, Method Area 모든 Thread가 공유한다.

  • PC(Program Counter) Registers(Thread별로 1개씩 존재) Thread가 생성될 때마다 생기는 공간이다. Java에서 Thread는 각자의 메서드를 실행하는데, PC Registers는 어떤 명령을 실행할지 관리하다.
  • JVM Stack(Thread별로 1개씩 존재) 지역변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값들이 생성되는 영역이다.
    class Animal {
    	private String name;
    	private float weight;
    
    	public Animal(String name, float weight) {
    		this.name = name;
    		this.weight = weight;
    	}
    }
    
    public class Main {
    	public static void main(String[] args){
    		String name = "Dog";
    		float weight = "3.14";
    
    		Animal animal = new Animal(name, weight);
    	}
    }
    • String name = "Dog"; 메모리 공간을 name이라고 잡아두고 메모리 영역에 “Dog”을 넣는다. 스택에 메모리에 이름이 name이라고 붙여주고 값이 “Dog”인 메모리 공간을 만든다.
    • Animal animal = new Animal(name, weight); 는 Animal animal은 스택 영역에 생성되고 new로 생성된 Animal 클래스의 인스턴스는 힙 영역에 생성된다.
    • 스택 영역에 생성된 animal 값으로 힙 영역의 주소값을 갖는다. 스택 영역에 생성된 animal은 힙 영역에 생성된 객체를 참조한다.
    • Java Stack 영역이 가득차면 StackOverflowError가 발생한다.(JVM의 전체적인 메모리가 부족하면 OutOfMemoryError가 발생한다.)
  • Native Method Stack(Thread별로 1개씩 존재)
    • 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.
  • Heap(모든 Thread가 공유)
    • 사용자가 관리하는 인스턴스가 생성되는 공간이다. 객체를 동적으로 생성하여 인스턴스가 Heap 영역의 메모리에 할당된다.
    • 프로그램을 시작될 때 미리 Heap 영역을 많이 할당해 놓으며 인스턴스와 인스턴스 변수가 저장된다.
    • 레퍼런스 변수의 경우 Heap에 인스턴스가 저장되는 것이 아니라 참조가 저장된다.
    • 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않은 메모리를 확인하고 제거한다.
  • Method Area(모두 Thread가 공유)
    • 클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보 같은 필드 정보와 메서드의 이름, 리턴 타입, 파라미터, 접근 제어자 정보 같은 메소드 정보, Type 정보(Interface or class), Constant Pool(상수 풀: 문자 사수, 타입, 필드, 객체 참조가 저장됨), static 변수, final class 변수 등이 생성되는 영역이다.
      • 정적 메서드 사용에 대한 고민들을 떠올려 보자.
    • 객체 생성 후에 메서드를 실행할 때, 해당 클래스 코드에 대한 정보를 Method Area에 저장한다.
    • 다른 메모리 영역에서 해당 정보에 대한 요청이 오면, 실제 메모리 주소로 변환해서 전달한다.

JAVA의 실행 과정과 JVM에 대한 설명으로 일단 메모리 구조(1)을 마친다.
공부하면서 느낀 점은 Java의 메모리를 이해하기 위해 공부할 내용이 아주 방대함을 깨달았다. 꼬리물기 방법으로 궁금한 점을 찾아가며 업데이트해보겠다.

Reference

profile
https://mywnajsldkf.tistory.com -> 이사 중

0개의 댓글