JVM 에 대해여
Java Virual Machine 은 Java bytecode 실행 시키기 위한 가상머신이다.
JVM 은 운영체제가 다르더라도 실행되는 내용은 같다.
JVM 에서 수행되는 자바 프로그램은 운영체제에 종속적이지 않으나 , JVM 자체는 운영체제에 종속적이다.
( 운영체제별로 JVM 을 설치해야됨.)
JVM 위와 같은 방식으로 인해 Write Once, Run Anywhere(WORA) 이 가능하다.
텍스트 형태로 되어 있는 소스코드를 컴퓨터가 알아들을 수 있게 기계어로 번역하는 것이다.
위와 같은 작업을 하는 프로그램을 compiler 라고 한다.
단순히 기계어로 번역하는게 아니라 각 언어의 문법 및 다른 오류가 있는지 확인하는 과정도 포함한다.
Java Compiler 는 java파일을 class 파일 (Java bytecode) 로 변환시켜준다.
1) public static void main(String[] args) 메인메서드가 포함된 자바파일 작성.
2) cmd 창 : javac 작성한파일.java --> 작성한파일.class 로 컴파일.
3) cmd 창 : java 작성한파일 --> 프로그램 실행
바이트코드(Bytecode, potable code, p-code) 는 특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법이다.
소스코와 비교하면 바이트코드는 덜 추상적이고 간결하며 더 컴퓨터 중심적이다.
자바 바이트코드의 경우 .class 파일의 확장자명을 갖는다.
JIT compile (Just-in-time complication, dynamic translation) 은 자바 컴파일러에 의해 생성된 바이트코드를 런타임에 기계어로 번역하는 컴파일 기법이다.
JIT 컴파일러는 바이트코드를 컴퓨터 프로세서로 직접 보낼수 있는 명령어로 바꾸는 프로그램이다.
자바 바이트코드는 기계어는 아니지만 JVM에 의해 기계어로 손쉽게 변활할 수 있는 코드이다.
인터프리터의 단점을 보완하기 위해 도입된 방식이다.
바이트코드 전체를 컴파일하여 기계어로 변경한다.
캐싱을 통해 재사용시 컴파일 없이 바로 기계어로 직접 실행한다.
JVM 은 크게 Class Loader, Execution Engine, Runtime Data Area 로 나눌 수 있다.
클래스 파일의 데이터를 Runtime Data Area에 적재 하는 역할을 한다.
Class Loader 는 Loading -> Link -> Initialization 순서로 진행된다.
Class Loader 는 Bootstrap/Extensions/System/User-Defined Class Loader 로 되어 있다.
클래스파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 메서드 영역에 저장 ( Full Qualified Class Name, Class, Interface, Enum, Method, Variables ) 로딩이 끝나면 해당 클래스 타입의 클래스 객체를 생성하여 힙영역에 저장한다.
Verify, Prepare, Resolve 세 단계로 이루어져 잇다. Verify 는 class 파일이 유효한지 체크 한다.
Prepare 는 클래스변수와 기본값에 필요한 메모리, Resolve 는 심복릭 메모리 레퍼런스를 메서드 영역에 있는 실제 레퍼런스로 교체한다.
static 변수의 값을 할당한다. static 블럭은 이때 실행이 됨.
$JAVA_HOME/jre/lib 에 있는 코어자바 라이브러리 ( rt.jar ) 를 로딩한다.
Native 로 구현되어 있음.
$JAVA_HOME/jre/lib/ext 에 있는 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 클래스를 로딩한다.
다음으로 CLASS PATH에 정의하거나 JVM Option 에서 -cp, -classpath 에 지정된 클래스를 로딩한다.
사용자가 직접 생성해서 사용하는 클래스로더 이다.
Class Loader 에 의해 Runtime Data Area 에 적재된 바이트코드들을 컴퓨터가 이해할 수 있는 기계어로 변경해 명렁어 단위로 실행하는 역할을 한다.
이때 명령어 하나씩 실행하는 인터프리터 방식이 있고 바이트코드를 네이티브 코드로 변환하는 JIT Compiler 방식이 있다.
클래스 파일들이 저장되어 있는 장소인 이곳에는 5가지 영역이 존재한다.
클래스 멤버 변수 이름, 데이터 타입, 리턴타입, 상수풀, static 변수 등이 저장됩니다. 클래스 수준의 정보가 저장됩니다. 여기에 저장된 정보들은 공유 됨니다.
new 키워드로 생성된 객체와 배열이 생성되는 영역이다.
메소드 영역에 로드된 클래스만 생성이 가능하다.
Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.
스레드가 생성될 때 마다 생성되는 영역으로, 대표적으로 지역변수가 여기에 저장된다.
메서드를 호출할 때마다 스택이 개별적으로 생성된다.
동시성(concurrency) 문제를 해결하기 위해서 메서드에 동기화 블럭(synchronized) 를 지정하는데, 동기화 블럭 없이 동시성 문제를 해결하는 방법중 하나가, 지역 변수를 이용하는 방법이 있다.
Thread(쓰레드)가 생성될 때마다 생성되는 영역이다.
Program Counter 즉, 현재 쓰레드가 실행되는 부분의 Java Virtual Machine Instruction의 주소와 명령을 저장하고 있는 영역이다.
이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 한다.
쓰레드가 생성되었을때 메서드와 힙영역은 모든 쓰레드가 공유하며, PC Register, Stack, Native Stack Area 는 공유되지 않는다.
자바 언어 이외의 언어로 작성된 코드를 저장하는 메모리 영역이다.
주로 native 키워드가 붙은 애들이 저장된다
말 그래도 자바 개발도구의 약자이다.
JDK 안에 JRE + 개발을 위해 필요한 도구 ( javac, java 등등... ) 를 포함한다.
자바 프로그램을 동작시킬때 필요한 라이브러리 파일과 기타 파일을 갖고 있다.
컴파일된 자바 프로그램을 실행할 수 있는 환경이다.