목적 파일
컴파일러나 어셈블러가 소스코드를 컴파일 또는 어셈블해서 생성한 파일
- c: 하나의 소스 코드로 각 기기에 맞는 목적 파일을 생성
- java: 하나의 소스 파일로 어느 JVM에서든 실행시킬 수 있는 목적 파일 생성
- 반 기계어인 바이트 코드로 목적 파일 생성(.class)
Java의 실행 과정
- Class Loader는 바이트 코드를 동적으로 JVM에 로딩하여 실행에 필요한 클래스를 Runtime Data Area에 로드
- Execution에 의해 기계어로 해석되어 실행
Class Loader
- 바이트 코드를 Runtime Data Area으로 로드해주는 역할
- 바이트 코드 로드 및 링크를 통해 배치하는 작업을 수행하는 모듈
- 실행될 때 동적으로 클래스를 로드하고 jar 파일 내부에 저장되어 있는 클래스들을 JVM에 로드
- Method Area: 클래스, 변수 및 메소드의 정보를 배치
- Heap Area: static 변수와 메소드의 정보를 배치
Execution
- 로드된 바이트 코드를 기계어로 해석하여 실행하는 역할
- Interpreter: 바이트 코드를 한줄 씩 번역 및 실행하는 역할
- JIT Compiler: 인터프리터 방식으로 실행을 하다가 적당한 시점에 바이트 코드 전체를 컴파일하여 캐싱하는 역할
- Garbage Collector: 사용되지 않는 메모리를 추적하여 비워주는 기능
Compiler, Interpreter
- 컴파일러는 목적 파일을 생성하여 실행한다.
- 소스코드가 많을 시, 컴파일 속도가 느릴 수 있다.
- 한 번 컴파일이 되면, 실행 속도가 빠르다.
- 인터프리터는 목적 파일을 따로 생성하지 않고, 한줄씩 바로 번역해서 실행한다.
- 목적 파일이 존재하지 않는다.
- 인터프리터만 존재하면 어디서든지 실행이 가능하기 때문에 자유롭고 독립적이다.
- 실시간으로 번역 되면서 실행되기 때문에 실행 속도가 느리다.
- Java는 JDK의 javac에 의해 바이트코드로 컴파일이 되고, JVM에서는 인터프리터로 실행된다. 즉, Java는 컴파일 언어지만 인터프리터의 특징을 동시에 가진다.
Runtime Data Areas
- 컴퓨터에서 메모리 같은 역할을 수행하는 영역
- 자바 프로그램을 실행하여 발생하는 데이터를 저장하는 역할
- 데이터의 속성에 따라 영역이 분리되어 있다.
PC Register
- 스레드가 시작될 때마다 생성되는 공간으로, 스레드마다 하나씩 존재
- 스레드가 어떤 명령에 의해 실행되어야 할지에 대한 기록을 하는 부분으로 현재 수행을 하고 있는 JVM의 명령 주소를 갖고 있다.
Native Method Stack
- 바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역
- 자바 이외의 언어로 작성된 코드를 실행할 때 할당되며, 일반적인 C 스택을 사용
- Java Native Interface를 통해 바이트 코드로 전환하여 저장
- 일반 프로그램처럼 커널이 스택을 잡아 독자적으로 프로그램을 실행시키는 영역
Method Area
- 클래스 정보를 처음 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 공간
- 클래스 타이브 변수 및 메소드 등의 정보를 가지며, 모든 Thread가 공유한다.
- Runtime Constant Pool
- 상수 자료형을 저장하여 참조하고 중복을 막는 역할을 수행
Heap Area
- 객체가 생성되는 영역
- 프로그램을 실행하는 중 생성되는 객체들은 모두 이곳에 생성된다.
- Permanent Generation
- 생성된 객체들의 정보의 주소값이 저장된 공간
- 클래스 로더에 의해 로드되는 Class, Method 등에 대한 Meta. 정보가 저장되는 영역이며, JVM에 의해 사용됨
- Reflection을 사용하여 동적으로 클래스가 로딩되는 경우에 사용
- Java 8 이전에는 Heap에 존재했지만, Method Area 즉, Metaspace라 불리우며 Heap이 아닌 Native 메모리 영역에 저장됨
- New/Young Generation
- Eden: 객체들이 최초로 생성되는 공간
- Survivor 0, 1: Eden에서 참조되는 객체들이 저장되는 공간
- 생명 주기가 짧은 객체를 가비지 컬렉터의 대상으로 하는 영역이다.
- Eden 영역에 객체가 가득차게 되면 가비지 컬렉터에 의해 Eden 영역에 있는 값들을 Survivor 1 영역에 복사하고 이 영역을 제외한 나머지 객체들을 삭제한다.
- Tenured generation
- Old: 이곳의 객체들은 가비지 컬렉터에 의해 삭제된다.
- New/Young Generation 에서 일정시간 참조되고 있고 살아남은 객체들이 저장되는 공간
- 생명 주기가 진 객체를 가비지 컬렉터의 대상으로 하는 영역
Stack Area
- 프로그램 실행 과정에서 임시로 할당이 되었다가 메소드를 빠져나가면 바로 소멸이 되는 특성의 데이터들을 저장하기 위한 영역
- 쌓이는 메소드의 단위를 스택 프레임이라고 부름
- 해당 메소드를 실행하기 위한 변수 및 블록이 존재하면 스택 프레임 내부에 스택 프레임이 생길 수 있다.
- 각 스레드가 고유의 스택 영역을 가진다.
Process
- 프로세스는 프로그램에서 사용되는 메모리등의 자원과 스레드로 구성
Thread
- 프로세스 내부에서 실제로 작업을 수행하고 있는 주체
Reflection
- 객체를 통해 클래스의 정보를 분석해 내는 프로그래밍 기법
변수
- 특정 메모리 영역에 이름을 붙이고 주소 대신에 이름을 사용해서 메모리에 값을 저장하고 읽을 수 있게 하는 것
변수의 여러가지 형태
- Camel case
- varTest
- Snake case
- var_test
- Pascal case (Java 에는 클래스명만 대문자로 시작하자는 암묵적인 규칙이 있어서 추천 X)
- VarTest
- Kebab case (Java 에서는 변수명에 - 기호 사용 불가)
- var-test
참조형
- 타입에 관계없이 변수의 크기가 항상 4byte이다.(JVM이 64bit일 경우 8byte)