JVM은 Java Virtual Machine의 약자이다. 자바의 대부분 강의에서 초반 부분에서는 System.out.println("Hello world")라는 java 코드를 막 작성하고 이것을 자바 컴파일러로 컴파일하고 콘솔로 실행시키는 실습을 많이 하곤 한다. 이 때 JVM이라는 용어가 등장한다. JVM 자체도 깊게 다루면 끝도 없고 컴퓨터 구조 관련 얘기가 무수히 나오기 때문에 그 땐 이야기를 자세히 다뤄주진 않는다. 이전에 시간을 따로 내서 정리해야 겠다는 생각을 했었고 그게 바로 지금인거 같아서 글을 작성하려 한다.
JVM
자바가 다른 언어와 구별되는 큰 장점으로 가장 많이 거론되는 것이 OS 플랫폼의 독립성이다. WORN(write once, run, anywhere)라는 말이 있는데 이말은 플랫폼 상관없이 한번 쓰기만 하면 어디에서나 동작가능하게 해준다는 말로 이를 가능하게 해주는 것이 바로 JVM이다. (반면 C언어는 OS에 종속적인 컴파일러가 해당 소스코드를 컴파일한다. 그래서 OS 종속적이다. )
JAVA의 실행
우리가 작성한 자바코드(.java확장자)는 자바 컴파일러가 컴파일하여 자바 바이트코드라는 것이 된다. 이것은 JVM이 실행할 수 있는 형태로 .class 확장자가 붙은 것이 바이트코드이다. JVM이라는 프로그램 자체는 물론 리눅스 전용 JVM, 윈도우 전용 JVM 따로 있지만 .class 파일을 받아서 해석하는 방식은 모두 통일된 방식으로 해석하기 때문에 OS 독립적이라 말한다. JVM이 동작하는 위치를 아래의 그림처럼 도식화 할 수 있다.

앞에서 언급한 .class는 아직 기계어가 아니다. 아직 중간언어인 셈이다. 이것이 다른 OS에 가더라도 동일하게 동작되는 형태인 것이며 아직 한번의 변환이 더 남았다. 그 과정은 중간언어와 주변 OS 정보들을 정리하여 해당 OS에 적합한 형태로 변환하는 과정이다. 이러한 작업을 하는 것이 Execution Engine이고 이 때 사용되는 방식은 인터프리터 방식으로 이 때 최종 기계어로 바꾸며 한줄 한줄 읽어가면서 실행이 된다. 하지만 같은 메소드라도 반복적으로 호출이 되면 매번 해석하고 수행하는데 있어서 속도가 느리기 때문에 이때 JIT 컴파일러가 사용된다. JIT 컴파일러는 자주 사용될 수 있는 bytecode를 캐싱하고 최적화함으로써 코드가 interpreter에 의해 여러번 변환되는 작업의 수를 줄일 수 있다. 이와 같이 자바는 컴파일러 방식과 인터프리터 방식을 모두 사용한다.

JVM 구성요소
이제 위 그림에서 구성 요소들을 하나씩 알아보려 한다.
- Garbage Collector
- 메모리 관리 기능을 자동으로 수행한다. 애플리케이션이 생성한 객체의 생존 여부를 판단하여 더이상 사용하지 않는 객체를 메모리 해제한다. ( Garbage Collector에 대한 동작원리는 나중에 정리하자 )
- Class Loader
- JVM내로 클래스를 로드(올림)하고 링크(배치)하는 작업을 수행하는 모듈로 런타임시 동적으로 클래스를 로드한다. Runtime Data Area에 올라간다.
- Execution Engine
- Class Loader를 통해 JVM 내 런타임 데이터 영역에 배치된 바이트 코드를 실행한다. 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
- Runtime Data Areas
- JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.
- 실서버에서 호스팅을 하던 중에 java.lang.OutOfMemoryError: Java heap space라는 에러가 나면 이쪽에서 나는 문제라 한다. ( 해결방법은 구글링~ )
- 해당 영역은 5가지로 구분된다. Method, Heap, Stack, PC Register, Native Method

Method Area, Heap Area는 모든 스레드가 공유하는 영역,
Stack Area, PC Register, Native Method Stack Area는 각 스레드마다 생성되는 개별영역이다.
공유의 형태를 다음과 같이 도식화할 수 있다.
(Heap은 모든 스레드가 공유하기 때문에 동기화 문제가 생길 수 있다는 것 주의!)

힙 영역은 가비지 컬렉션에 대상이 되는 공간인데 효율적인 가비지 컬렉션을 수행하기 위해
다음과 같이 여러 영역으로 나뉜다.

- Young Generation : 생명주기가 짧은 객체를 GC 대상으로 한다.
- Eden : new를 통해 새로 생성된 객체가 위치되고 정기적인 쓰레기를 수집하고나서 살아남으면 Survivor로 이동된다.
- Survivor1/2 : 살아남은 객체가 순차적으로 이동된다.
- Old Generation : 생명 주기가 긴 객체를 GC 대상으로 하는 영역, Young Generation에서 마지막까지 살아남은 객체가 이동
- Permanent : 클래스와 메소드 메타 정보가 저장된 공간이다. static 변수와 static 메소드가 저장되는 공간
- java8부터 heap space가 아니다. native area로 이동
- metaspace라는 용어로 변함
- 나중에 읽어볼 것
- 참고
- https://hoonmaro.tistory.com/19
- https://velog.io/@recordsbeat/Garbage-Collector-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%95%8C%EA%B8%B0
- https://inpa.tistory.com/entry/JAVA-%E2%98%95-JVM-%EB%82%B4%EB%B6%80-%EA%B5%AC%EC%A1%B0-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD-%EC%8B%AC%ED%99%94%ED%8E%B8#%EB%9F%B0%ED%83%80%EC%9E%84_%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%98%81%EC%97%AD_runtime_data_area
마로의 Java(자바) 정리 - 8. 자바 메모리 구조
JVM 구조 실행될 클래스 파일을 메모리에 로드 후 초기화 작업 수행 메소드와 클래스변수들을 해당 메모리 영역애 배치 클래스로드가 끝난 후 JVM은 main 메소드를 찾아 지역변수, 객체변수, 참조
hoonmaro.tistory.com
☕ JVM 내부 구조 & 메모리 영역 💯 총정리
저번 포스팅에서는 JRE / JDK / JVM에 대해서 간략하게 알아보는 시간을 가졌다면, 이번 포스팅에서는 JVM의 내부 구조에 대해 좀 더 자세하게 알아보도록 할 예정이다. JVM(자바 가상 머신)은 자바 언
inpa.tistory.com
Garbage Collector 제대로 알기
ㅅㅅ슈규슈슉 g..gc 슈슉 g...gc GC! 슈슉
velog.io