JVM과 메모리 구조

지윤·2021년 1월 19일
0

Java

목록 보기
4/21

Java 클래스 변수(static)를 공부하다가 메모리 구조에 대해서 궁금해져서 간단하게 정리

JVM(Java Virtual Machine)

자바 가상 머신은 Java Byte Code(자바 소스 코드)를 다양한 OS에 맞게 해석하여 실행시키는 가상의 기계라고 할 수 있다.

Java compiler는 .java 파일을 JVM이 이해할 수 있는 .class(Java byte code) 파일로 변환시켜 준다.

따라서 Java Byte Code는 JVM 위에서 OS와 상관없이 실행될 수 있는 것이다. 이는 Java의 큰 장점이다.

단, 자바 프로그램은 OS에 독립적이지만, JVM은 운영체제에 종속적이다. 또한, 실행 과정에서 JVM을 거쳐야 하므로 상대적으로 속도가 느린 단점이 있으며, 이는 JIT 컴파일러를 통해 단축시킬 수 있다.

JVM은 자바 인터프리터(interpreter), 클래스 로더(class loader), JIT 컴파일러(Just-In-Time compiler), 가비지 컬렉터(garbage collector) 등으로 구성되어 있다.


JIT complier

JVM의 해석이 필요하여 C언어에 비해 상대적으로 속도가 느린 부분은 JIT(Just In Time) complier로 극복했다. JIT는 ByteCode를 어셈블러 같은 NativeCode로 바꿔서 실행이 빠르지만 변환 비용이 발생한다.

따라서 JVM은 모든 코드를 JIT Compiler 방식으로 실행하지 않고 Interpreter 방식을 사용하다가 일정한 기준이 넘어가면 JIT Compiler 방식으로 실행한다.


JVM 과정

  1. 실행될 클래스 파일을 메모리에 로드 후 초기화 작업 수행
  2. 메소드와 클래스변수들을 해당 메모리 영역애 배치
  3. 클래스 로드가 끝나면 JVM은 main 메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓음
  4. 다음 라인을 진행하면서 상황에 맞는 작업 수행(함수 호출, 객체 할당 등)

JVM 구성요소

Class Loader

  • RunTime 시점에 JVM 내로 클래스를 로딩하게 해주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드한다.

Runtime Data Areas

  • JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간으로 Class Loader에서 준비한 데이터들을 보관하는 저장소이다.
  • 크게 5가지 영역 PC Register, JVM Stack, Native Method Stack, Method Area, Heap으로 구성된다.

Excution Engine

  • Load된 Class의 ByteCode를 실행하는 Runtime Module이다. Class Loader를 통해 JVM 내의 Runtime Data Areas 에 배치된 바이트 코드는 Executin Engine에 의해 실행되며, 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.


Runtime Data Areas 구성요소

PC Register

  • 각 Thread 별로 하나씩 존재하며, 현재 수행 중인 JVM 명령 주소를 갖는다.

Native Method Stack

  • 자바 외 언어로 작성된 네이티브 코드를 위한 Stack이다. 즉, JNI(Java Native Interface)를 통해 호출되는 C/C++ 등의 코드를 수행하기 위한 스택이다.

JVM Stack

  • Thread의 수행 정보를 Frame을 통해서 저장하게 된다. Thread가 시작될 때 생성되며, 각 Thread 별로 생성이 되기 때문에 다른 Thread에는 접근할 수 없다.
  • main 메서드 호출
  • 메소드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터값 저장
  • Heap 영역의 메모리 참조 값을 저장(참조변수)
  • 메서드를 호출하면 생성되고 메서드 종료 시 바로 소멸한다.

Method Area

  • 모든 쓰레드가 공유하는 공유 메모리(Static) 영역이다.
  • Class Loader가 적재한 클래스(또는 인터페이스)에 대한 메타데이터 정보가 저장된다. 이 영역에 등록된 class만이 Heap에 생성될 수 있다.
  • 클래스, 인터페이스, 메소드, 필드, static 변수 등의 바이트 코드 등을 보관한다.
  • 이 영역에 적재되면 프로그램이 종료될 때 까지 유지된다.

Heap

  • 모든 쓰레드가 공유하는 공유 메모리(Static) 영역이다. 그렇기에 동기화 문제가 발생할 수 있다.
  • JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.
  • 따라서 new 연산자로 생성된 객체 또는 객체(인스턴스)와 배열을 저장한다. 즉, 참조형(Reference Type)의 데이터 타입을 갖는 객체(인스턴스), 배열 등을 저장한다.
  • 참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다. 즉, 가비지 컬렉터(GC)가 주기적으로 정리한다.
  • 반드시 스택 영역을 통해서 접근할 수 있다.


Garbage Collection (GC)

등장 배경
1. 객체는 금방 접근 불가능 상태(unreachable)가 되는 것
2.오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다는 것

Heap의 인스턴스 중 Thead의 JVM stack에서 도달할 수 없는 것들(Unreachable)이 GC의 대상이 되며, 이 방식을 Mark and Sweep 이라고 한다. 자세한 내용 참고


참고
https://medium.com/@lazysoul/jvm-%EC%9D%B4%EB%9E%80-c142b01571f2
https://hoonmaro.tistory.com/19
http://www.tcpschool.com/java/java_intro_programming
http://blog.naver.com/PostView.nhn?blogId=heartflow89&logNo=220954420688
https://jithub.tistory.com/40

profile
헬로🙋‍♀️

0개의 댓글