- JVM이란 무엇인가
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
- 프리미티브 타입 종류와 값의 범위 그리고 기본 값
- 프리미티브 타입과 레퍼런스 타입
- 1차 및 2차 배열 선언시 자바에선 어떤일이 벌어지는지(영역, 포인터, 주소 등)
1. JVM(Jave Virtual Machin)이란?
간단하게 말하면 자바를 실행하기 위한 가상 기계 이다.
실제 컴퓨터로부터 JAVA 어플리케이션 실행을 위한 메모리를 할당 받아 Runtime data를 구성한다.
Java는 어떠한 플랫폼에 영향을 받지 않지만 JVM은 윈도우의 JVM과 리눅스의 JVM은 서로 다르다.
Java의 소스코드는 JVM을 거쳐서 OS에 도달하므로 JVM이 인식할 수 있는 java bytecode(.class)로 변환된다.
이 때 JVM은 OS가 bytecode를 이해할 수 있도록 해석해주는 역할을 한다.
2. 바이트 코드는 무엇인가

컴파일 단계에서 JAVA 클래스 파일을 JAVA 컴파일러가 변환할 때 나오는(.class) 안에 존재하는 데이터이다.
바이트 코드의 구성 요소는 모두 적기도 힘들고 내가 이해하기도 힘들어서 이정도만 짚고 넘어가겠다.
3. JIT 컴파일러란 무엇이며 어떻게 동작하는가
JIT(Just In Time)은 기존의 JVM의 Interpreter 방식이 속도가 느리기 때문에 실행 과정에서 컴파일 할 수 있도록 만들어졌다.
정적 컴파일러만큼 빠르면서 인터프리터 언어의 빠른 응답속도를 추구하기 위해 사용된다.

JIT 컴파일러는 해당 메서드의 바이트코드를 기본 기계어 코드로 컴파일하고 적시에 실행하도록 컴파일한다.
JIT 컴파일에는 프로세서 시간과 메모리 사용량이 필요하다.
이론적으로 컴파일에 프로세서 시간과 메모리 사용량이 필요하지 않은 경우 모든 메서드를 컴파일하면 java 프로그램 속도가 기본 애플리케이션의 속도에 근접할 수 있다.
4. JVM 구성 요소
![]()
Class Loader
.java 확장자 파일을 바이트 코드인 .class 확장자로 바꾼다.
.class 파일을 엮어서 JVM이 운영체제로부터 할당받은 메모리인 Runtime Data Area로 Loader한다.
Execution Engine
클래스를 실행시키는 역할이다.
Class Loader에 의해 메모리에 Load된 .class 파일을 기계어로 변경해 명령어 단위로 실행한다.
Interpreter 방식과 JIT 방식이 있다.
Garbage Colletor
Heap 메모리 영역에 생성된 객체들 중 참조가 끊긴 객체들을 찾아 제거하는 역할이다.
Runtime Data Area
자바 어플리케이션을 샐행할 때 사용되는 데이터를 Load하는 영역이다.
![]()
PC Register
Thread가 생성될 때마다 생성되는 영역이다.
현재 Thread가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다.
JVM stack
지역 변수, 파라미터 등 연산에 사용되는 임시 값들이 생성되는 영역이다.
매서드가 호출되면 각각의 스택 프레임이 생성되고 수행이 끝나면 프레임 별로 삭제한다.
Native method stack
Thread에서 Native 방식의 메소드가 실행되는 경우 Native Method Stack에 쌓인다.
C언어로 작성된 메소드가 있다면 해당 메소드는 Native Stack에 쌓인다.
Runtime Constant Pool
상수 자료형을 저장하여 참조하고 중복을 막는 역할을 수행한다.
Heap 영역
new 연산자로 생성되는 객체와 배열을 저장한다.
메서드 영역에 로드된 Class만 생성가능하고 Garbage Collector가 참조가 끊긴 객체를 제거한다.
5. JDK와 JRE의 차이점
JDK(Java Development Kit)
Java를 사용하기 위해 모든 기능을 갖춘 Java용 SDK이다.
프로그램을 생성, 실행 컴파일할 수 있다.
JRE(Java Runtime Environment)
컴파일 된 Java 프로그램을 실행하는데 필요한 패키지이다.
프로그램을 코딩할 때 JDK가 아닌 JRE를 사용한다면 컴파일이 정상적으로 되지 않는 등 문제점이 발생할 수 있다.
6. Java Primitive 타입 종류와 값의 범위 그리고 기본 값
종류
1. int
32비트의 메모리를 가진다.
선언 후 값을 할당하지 않았을 때 0이 할당된다.
10진수이다
2. byte
8비트의 메모리를 가진다.
3. short
16비트의 메모리를 가진다.
4. long
64비트의 메모리를 가진다.
5. float
32비트의 메모리를 가진다.
소수점은 양수와 음수 모두를 대응한다.
기본값은 0.0(0이 아니다)
마지막에 f를 붙어야 된다.
6. double
64비트의 메모리를 가진다.
마지막에 d를 붙여야 한다.
7. boolean
단 두 가지의 값만 저장한다.
1비트의 메모리를 가진다.
기본값은 false이다.
8. char
16비트의 메모리를 가진다.
기본값은 '\u0000’이다.
유니코드로 표현이 가능하다.
7. Primitive 타입과 Reference 타입
primitive type
8가지의 기본형 타입을 미리 정의하였다.
Null이 존재하지 않는다. Null을 넣고 싶으면 wrapper class를 사용하면 된다
실제 값을 저장하는 공간으로 스택 메모리에 저장한다.
문법상 에러가 나는 경우가 많다.
Reference 타입
기본형 타입을 제외한 타입들이 모두 참조형 타입이다.
주소값을 저장하는 공간으로 힙 메모리에 저장된다.
문법상으로는 에러가 없지만 실행시켰을 때 에러가 나는 경우가 있다
8. 1차 및 2차 배열 선언시 자바에선 어떤일이 벌어지는지
int[] arr = new int[3];
int[][] arr2 = new int[3][3]
배열은 Reference 타입이므로 실제 값이 저장되는 공간은 Heap 공간에 저장된다.
하지만 이 값이 저장되어 있는 곳의 주소값을 저장하는 공간은 arr라는 스택 영역의 메모리에 담기게 된다.
배열은 초기화를 하지 않아도 해당 자료형의 기본값으로 설정이 된다.
2차원 배열은 1차원 배열에서 각 힙 영역에 있는 값이 실제 저장된 값이 아닌 다른 힙 영역에 있는 주소값의 위치를 알려주는 형태로 작용한다.