어제 기술면접 스터디를 하면서 모의면접을 했는데 자바에 대한 질문을 정리를 해볼 필요가 있다고 느껴졌다.
write once, run anywhere. 자바를 표현하는 대표적인 문구입니다. 자바의 가장 큰 특징은 플랫폼 독립적인 언어입니다. 소스코드를 한 번만 작성하면 컴파일러가 바이트 코드인 클래스 파일을 생성하고, 가상머신인 JVM이 실행시킵니다. JVM이 설치될 수 있는 플랫폼이라면, JVM이 각각의 운영체제에 맞춰 결과적으로 똑같이 돌아갈 수 있도록 실행합니다.
그리고 자바는 처음부터 객체지향으로 만들어진 언어입니다. 설계도 역할을 하는 클래스에 객체의 속성인 필드와 행동을 정의한 메서드가 정의되어있고, 이를 통해 객체를 생성해서 객체간의 상호작용으로 데이터를 처리하는 언어입니다.
자동으로 메모리 관리를 지원해 안정성이 높고 역사가 길어서 수많은 레퍼런스가 있는 언어입니다.
개발자가 자바 소스파일을 작성합니다. JDK의 자바 컴파일러가 소스파일을 클래스 파일로 컴파일합니다. JVM의 클래스로더가 클래스 파일을 전달받아 필요한 클래스들을 동적로딩으로 JVM의 runtime data area에 로드합니다. JVM의 인터프리터가 한줄씩 읽어 기계어로 변환해 실행하다가, Jit 컴파일러가 동적으로 바이트 코드를 기계어로 컴파일해 성능을 향상시킵니다. JVM이 프로그램의 실행을 계속 진행하면서 필요에따라 가비지 컬렉션 같은 작업을 수행합니다.
JDK는 자바 개발 도구로, JRE와 자바 컴파일러와 디버그 도구 같은 개발 툴을 합친 개념입니다. JRE는 자바 실행환경으로 JVM과 자바 프로그램 실행에 필요한 라이브러리를 합친 것입니다. 실행전에 main 메서드가 있는지 확인하고 있으면 JVM을 부팅합니다. JVM은 자바 클래스 파일을 실행시키는 가상머신입니다. JVM만 설치 되어 있으면 어떤 운영체제에서도 자바를 실행할 수 있습니다.
클래스 파일을 메모리에 동적으로 로드하는 클래스로더, 인터프리터와 JIT 컴파일러가 포함되어 실질적으로 코드를 실행하는 실행엔진, 메모리를 자동으로 관리하는 가비지컬렉션, 메모리영역인 Runtime data area로 구성되어 있습니다.
가비지컬렉터는 JVM에 위치해, 자바의 메모리 관리를 담당합니다. 프로그램에서 더이상 사용되지 않는 객체를 찾고, 해당 객체가 차지하는 메모리를 회수해 사용가능한 메모리로 만듭니다. 이를 통해 개발자가 직접 메모리를 해제하는 번거로움을 줄이고 메모리 누수와 같은 문제를 예방합니다.
JVM의 메모리 영역은 Runtime Data Area라고 합니다. JVM이 OS로 부터 메모리를 할당 받아 자바 프로그램을 실행하면서 발생하는 데이터를 저장하는 영역입니다. 모든 쓰레드가 공유하는 영역인 Heap과 method 영역이 있고, 쓰레드 별로 하나씩 존재하는 PC Register, JVM 스택, Native Method Stack이 있습니다.
메서드 영역은 클래스로더에 의해서 로드된 클래스와 인터페이스의 정보와 바이트코드, 그리고 정적변수와 상수 값이 저장됩니다.
Heap은 런타임 시에 동적으로 할당해 사용하는 영역입니다. new 연산자로 생성된 인스턴스와 배열이 저장됩니다. 가비지 컬렉터에 의해 관리되어 참조되지 않는 객체는 정리됩니다.
JVM 스택은 쓰레드 마다 별도로 생성되는 영역으로, 메서드 호출 시 메서드의 정보와 지역변수가 저장됩니다. 가장 처음 실행되는 main 메서드가 처음으로 올라가고 그 후 호출 되는 메서드들이 프레임이라는 단위로 쌓이고 메서드가 반환될때 제거되는 구조입니다.
PC Register는 각각의 쓰레드가 시작될 때 마다 생성됩니다. 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장합니다.
Native Method Stack는 자바 코드가 아닌 다른 언어로 작성된 네이티브 메서드를 실행하기 위한 스택입니다. 자바 코드 외부에서 실행되는 메서드의 호출과 실행 정보를 저장합니다.