자바는 객체 지향 언어로 개발된 프로그래밍 언어다. 자바는 자바 가상 머신을 사용하여, 운영체제와는 독립적으로 동작할 수 있다. 따라서 자바는 어느 운영체제에서나 같은 형태로 실행될 수 있다. 자바 언어의 장점으로는 자동 메모리 관리를 지원하여 다른 언어에 비해 안정성이 높다는 점이 있다.
JVM(Java Virtual Machine)은 자바를 실행하기 위한 가상 기계(컴퓨터)라고 할 수 있다. JVM을 사용함으로써 OS에 종속받지 않고 CPU가 자바를 인식하고 실행할 수 있다.
자바 소스코드(.java)는 CPU가 인식하지 못하기 때문에 기계어로 컴파일을 해야 한다. 하지만 자바는 JVM이라는 가상머신을 거쳐 OS에 도달하기 때문에 OS가 인식할 수 있는 기계어로 바로 컴파일 되는 것이 아니라 JVM이 인식할 수 있는 java bytecode(.class)로 변환된다. 즉, 자바 컴파일러가 .java
파일을 .class
라는 java bytecode로 변환한다.
변환된 bytecode는 기계어가 아니기 때문에 바로 OS에서 실행되지 않는다. JVM이 OS가 bytecode를 이해할 수 있도록 해석해준다. 따라서 bytecode는 JVM 위에서 OS 상관없이 실행될 수 있다.
기계어는 컴퓨터가 인식할 수 있는 0과 1로 이루어진 바이너리 코드이다.
bytecode(바이트코드)는 JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미한다. bytecode는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다. 인터프리터나 JIT 컴파일러를 사용해 JVM 내부에서 기계가 실행할 수 있는 형태로 변경한다.
자바 컴파일러는 JDK를 설치하면 bin 폴더 안에 javac.exe
라는 실행 파일 형태로 존재한다. javac
명령어를 통해 .java
파일을 .class
로 컴파일 할 수 있다.
1) java 파일이 있는 경로로 이동한다.
2) javac [파일명].java
명령어로 .class
파일을 생성할 수 있다.
JDK 디렉토리의 bin 폴더 안에 JVM을 구동시키기 위한 명령 프로그램인 java.exe
가 존재한다. java
명령어로 JVM을 실행시킬 수 있다.
1) .class 파일이 있는 경로로 이동한다.
2) java [.class 파일 이름]
을 입력해 java 코드를 실행시킨다.
JVM은 다음과 같이 구성되어 있다.
자바는 런타임에 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크하는 특징이 있다. 이 동적 로드를 담당하는 부분이 JVM의 클래스 로더이다.
클래스를 실행시키는 역할로, 클래스 로더에 의해 메모리에 적재된 bytecode를 실제로 JVM 내부에서 기계가 실행할 수 있는 형태로 변경해 명령어 단위로 실핸하는 역할을 한다.
인터프리터
실행 엔진은 bytecode를 명령어 단위로 읽어서 실행한다. 따라서 속도가 느리다는 단점이 있다.
JIT 컴파일러 (Just-In-Time)
인터프리터 방식으로 실행하다가 적절한 시점에 bytecode 전체를 컴파일하여 기계어로 변경한 후, 더이상 인터프리팅하지 않고 기계어로 직접 실행하는 방식이다.
가바지 컬렉터
더이상 사용되지 않는 인스턴스를 찾아 메모리에서 삭제한다.
JVM의 메모리 영역으로, 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간이다. PC 레지스터, JVM 스택, 힙 메소드 영역, 런타임 상수 풀, 네이티브 메소드 스택으로 구분되어 있다. 자세히
//런타임 데이터 영역과 가비지 컬렉터에 대해 이후에 자세히 다뤄보겠다.