[Java] Java 의 동작
zl존석동
·2021. 12. 20. 21:55
다룰 내용
Compiler vs Interpreter
Java의 동작과정과 JVM
JDK vs JRE
Compiler, Interpreter
우리가 사용하는 프로그래밍 언어는 사람이 작성하였고 사람을 위한 코드입니다.
프로그래밍 언어로 작성한 어떤 프로그램을 컴퓨터가 실행시키도록 하여 의미가 있게 하여야겠지요.
하지만 컴퓨터가 이해할 수 있는 언어는 0과 1로만 이루어진 기계어입니다.
기계어?
기계어는 프로그램을 나타내는 가장 낮은 단계의 개념으로
CPU가 직접 해독하고 실행할 수 있는 비트 단위로 쓰인 컴퓨터 언어를 통틀어 말합니다.
컴파일러와 인터프리터는 사람이 만든 코드를 컴퓨터가 읽어서 실행시킬 수 있게끔 번역해줍니다.
Compiler
컴파일러는 작성한 고급언어 코드 전체를 한번에 목적코드(기계어)로 번역하여 실행 프로그램을 생성한다.
코드를 수정하고 실행하려면 다시 컴파일해야 하며 컴파일된 파일은 OS에 의존적이다.
예) C언어 프로그램의 컴파일된 윈도우 파일 ??.exe 는 리눅스에서 실행할 수 없다.
Interpreter
인터프리터는 추가로 실행파일을 생성하지 않고 고급언어 코드 프로그램을 기계어로 바로 번역하지 않고
중간 형태로 변환시킨다음 이를 각 행을 연속적으로 분석하며 실행한다.
실행속도는 컴파일러에 비해 느리지만 코드를 수정하고도 즉시 실행할 수 있다.
컴파일러 vs 인터프리터 예시로 겉을 핥아 보자
다음과 같은 어떤 일련의 고급언어 코드가 있다고 생각해봅시다.
a := 1;
b := 2;
c := a + b;
print(c);
컴파일러는 프로그래머가 작성한 인간스러운 소스코드를
나중에 실행시킬 수 있도록 하는 바이너리 코드(컴퓨터가 읽을 수 있는 0과1로 된)로 먼저 모두 변환한 다음
실행시 RAM에 로드되고 CPU가 연산하도록 한다.

인터프리터는 a:=1 이라는 구문을 먼저 읽고 RAM에 로드한 다음 바이너리 코드로 변환하여 CPU가 연산하게끔 하는 방식으로 순차적으로 b:=2 , c:=a+b 등등 작업을 수행해 나간다.

컴파일러는 번역, 실행이 분리되어 있는 느낌이라면 인터프리터는 합쳐져 있는 느낌이라고 할 수 있는데
왜 인터프리터가 컴파일러 프로그램을 실행하는 것 보다 느린지 감을 잡아볼 수 있다.
그래서 Java는 ??
컴파일러 + 인터프리터라고 할 수 있다.
우리가 만든 .java 파일을 이용해 javac 컴파일러가 자바가상머신(JVM) 고유의 특수한 중간 기계어 개념인 바이트 코드로 번역한 .class 파일을 생성한다. (빌드 프로세스를 통해)
이 .class 바이트 코드는 운영체제에 맞는 자바 가상 머신(JVM)에서 먼저 해석되고 운영체제에 맞는 완벽한 실행 파일로 바뀐다.
즉 .class 파일을 만들어 두면 운영체제에 맞는 가상머신으로 어느 OS에서나 실행 할 수 있게 된다.
JIT?
JVM은 성능 향상을 위해 런타임 중에 JIT 컴파일러도 사용한다.
JVM에서 인터프리터 방식으로 해석하다가 적절한 시점에 바이트 코드 전체를 컴파일 하는 것이다.
Just In TIme 컴파일러는 실행 시점에 기계어 코드를 생성하고 같은 코드가 반복될 때 매번 기계어 코드를 재생성하지 않고 재사용 한다.
OS에 맞게 바이트 실행 코드로 한번에 변환하여 실행하기 때문에 이전 방식인 자바 인터프리터 방식보다 성능이 훨씬 좋다고 한다.
Java 동작과 JVM
Java 프로그램의 동작 과정
자꾸 JVM 이라는 단어가 나온다!
뭔지 모르겠지만 먼저 자바프로그램이 어떤 순서로 실행되는지부터 알아보자

1) 작성한 자바코드(.java) 를 자바 컴파일러를 통해 자바 바이트 코드로 컴파일한다.
2) 컴파일된 바이트코드가 JVM의 Class Loader에게 전달된다.
3) Class Loader는 필요한 클래스들을 로딩, 링크하여 JVM Memory(Runtime Data Area)에 올린다.
4) Execution Engine에서 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 가져와 해석된다.
5) 해석된 바이트 코드들이 JVM Memory 에 적재되고 수행된다.
JVM(Java Virtual Machine)?
JVM은 자바 프로그램 실행 환경을 만들어 주는 소프트웨어이다.
JVM은 프로그램 실행 시 OS로부터 프로그램에 필요한 메모리를 할당 받고
자바 프로그램을 클래스 로더를 통해 읽어들여 실행하는 역할을 한다.
OS와 자바 사이에서 자바가 OS에 구애받지 않고 동작할 수 있게 해주는 역할을 한다.
프로그램이 동작 할 떄 메모리관리 와 가비지 컬렉션을 수행한다.
가비지 컬렉션?
프로그램에서 동적으로 할당했던 영역에서 더 이상 사용하지 않게 된 메모리(가비지) 를 자동으로 해제하는 기능
운영체제에 맞는 JRE(Java Runtime Environment)가 설치 되어있다면 JVM이 설치된 것으로 볼 수 있다.
JVM 구조와 역할

Class Loader
주요 역할은 컴파일된 클래스 파일을 JVM 메모리에 가져오는 것이다.
- 런타임 시에 동적으로 로드한다.
하나의 클래스는 클래스로더에 의해 한 번만 가져와지는데 컴파일 된 클래스를 모두 가져오는게 아니라
가져오는 것을 미뤄두었다가 프로그램에서 클래스가 호출 되었을 떄 가져오게 된다.
Execution Engine
바이트 코드들을 명령어 단위로 읽어서 실행한다. 즉 클래스를 실행시키는 역할을 한다.
클래스 로더에 의해 JVM 메모리에 적재된 바이트 코드는 Execution Engine 에 의해 실행되는 것이다.
인간다운? 자바 바이트 코드를 기계가 수행하기 힘드니 머신 네이티브한 코드로 변환이 필요하기 떄문에
인터프리터와 Jit 컴파일러를 사용하게 된다.
Interpreter
JVM은 플랫폼 중립적이기 때문에 인터프리터를 사용하여 바이트 코드를 실행한다.
JIT Compiler
반복되는 메서드 호출에 대해 바이트코드를 네이티브 코드로 적정 시점에 한번에 컴파일하여 성능을 향상시킨다.
Garbage Collector
참조되지 않은 모든 객체를 수집하고 제거한다.
JVM Memory
프로그램 수행을 위해 OS로부터 할당 받은 메모리 공간으로 자바 애플리케이션 실행 시 사용되는 데이터들을 적재한다.
Method Area
모든 스레드가 공유하며 class,interface,method,static 등의 바이트 코드를 보관한다.
Heap Area
모든 스레드가 공유하며 GC가 참조되지 않은 메모리 작업하는 영역이다.
Method Area에 로드된 클래스만 생성할 수 있다.
new로 생성된 객체가 생성된다.
Stack Area
메소드 호출마다 메소드만을 위한 공간을 만들어 매개변수, 로컬변수, 리턴 등
연산할 때 저장해두었다가 메소드 동작이 종료되면 자동으로 해제한다.
JDK vs JRE
아까 JRE 에서 JVM이 동작한다고 했는데 JRE가 뭐죠?
JRE(Java Runtime Environment)
자바 실행환경
JRE는 자바 코드를 받아서 필요한 라이브러리와 결합한 다음 이 코드를 실행할 JVM을 시작하는 온디스크 시스템이다. JRE에는 자바 프로그램 실행에 필요한 라이브러리와 소프트웨어가 포함된다
즉 자바 기반 애플리케이션을 실행시키려면 필요하다.
JDK(Java Development Kit)
자바 개발키트
개발자들이 JVM과 JRE에 의해 실행되고 구동될 수 있는 자바 프로그램을 생성할 수 있게 해준다.
Ref
Is Java a Compiled or Interpreted Language?
Compiled vs. Interpreted Programming Languages
https://www.itworld.co.kr/t/62076/%EA%B0%80%EC%83%81%ED%99%94/110768
'Java' 카테고리의 다른 글
| [Java] Abstract , Interface (0) | 2022.01.09 |
|---|---|
| [Java] 람다식이란 (0) | 2022.01.06 |
| [Java] 중첩 클래스 (0) | 2022.01.05 |
| [Java] 자바는 Call by Value (feat. C++) (0) | 2022.01.04 |
| [Java] 자바 메모리 구조와 변수 타입 (0) | 2021.12.22 |