'자바의 정석' 3판 책을 보면서 스터디하는 내용을 정리하고 있습니다.
틀리거나 추가 설명이 필요한 부분이 있으면 댓글로 알려주시면 감사하겠습니다! 👩💻🐈
학습 목표
- JAVA의 특징
- 컴파일 및 실행하는 방법
- JVM이란 무엇인지와 구성 요소
- 바이트코드와 바이너리코드의 차이
- JIT 컴파일러란 무엇인지와 동작하는 법
- GC란 무엇인지
- JDK와 JRE의 차이
JAVA의 특징
- 운영체제에 독립적
- 객체지향언어
- 자동 메모리 관리(Garbage Collection)
- 네트워크와 분산처리를 지원
- 멀티쓰레드 지원
- 동적 로딩을 지원
(장점: 실행시에 모든 클래스가 로딩되지 않고 필요한 시점에 로딩한다. 일부 클래스가 변경되어도 전체 애플리케이션을 다시 로딩하지 않아도 된다.)
컴파일 및 실행 과정
자바 컴파일러 javac이 java source file을 컴파일해서 실행가능한 바이트 코드를 생성한다.
이 코드로 JVM이 실행해서 OS에 올라간다.
JVM
_운영체제에 독립적_인 자바의 특징은 JVM을 통해 이루어진다. JVM은 자바를 실행하기 위한 가상머신이다. JVM은 OS에 종속적이어서 다양한 OS용 JVM이 존재한다. (OS가 달라서 가상머신을 돌린다 -> 자바에서 나온 개념.)
JVM interpreter로만 실행되면 실행시에 해석되기 때문에 속도가 느리다는 단점이 있다. 그래서 요즘엔 JIT컴파일러를 사용하여 컴파일된 자바코드(바이트코드)를 하드웨어의 기계어로 바로 변환해서 이를 보완하고 있다.
<JVM의 구성요소>
- 자바 인터프리터(interpreter)
자바 바이트코드를 한 줄씩 실행한다. - 클래스 로더(class loader)
- Loading
클래스 파일을 읽어서 적절한 바이트 코드들을 생성하고 "메소드" 영역에 저장
로딩이 끝나면 객체를 "힙" 영역에 저장 - Linking
- Verify - 클래스 파일 형식이 유효한지 체크
- Prepare - 클래스 변수의 기본값에 따른 필요한 메모리 준비
- Resolve - 참조변수(심볼릭 메모리 레퍼런스)를 "메소드" 영역의 실제 레퍼런스로 교체
- Initialization
super class, static 변수에 값을 할당
- Loading
- JIT 컴파일러(Just-In Time compiler)
전체 바이트 코드를 컴파일하고 캐시에 보관해놓고 직접 실행한다. - 가비지 컬렉터(garbage collector)
메모리 관리를 자동으로 해줌.
바이트 코드와 바이너리 코드 (bite code & binary code)
바이트 코드는 자바 가상 머신이 이해할 수 있는 언어로 변환된 코드를 의미한다.
자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불린다.
자바 바이트 코드의 확장자는 .class
바이너리 코드는 이진수로 된 코드다.
C언어에서 컴파일 후 생성되는 목적 파일이 바이너리 코드로 되어 있다.
그런데 기계어도 이진수로 되어 있지만 모든 바이너리 코드가 기계어는 아니다. 그래서 목적파일을 실행파일(완전한 기계어!)로 변환해야 컴퓨터가 제대로 이해할 수 있다.
JIT 컴파일러 (dynamic translation)
인터프리터 방식으로 실행하다가 적절한 시점에 바이트코드 전체를 컴파일해서 네이티브코드로 변경하고 직접 실행하는 방식이다.
네이티브 코드는 캐시에 보관하기 때문에, 한 번 컴파일된 코드는 빠르게 수행한다.
JIT 컴파일러는 두 가지 형태로 나뉜다.
c1(컴파일러 1, 클라이언트 컴파일러) & c2(컴파일러 2, 서버 컴파일러)
클라이언트 컴파일러는 서버 컴파일러보다 먼저 컴파일하기 시작한다.
서버 컴파일러는 클라이언트 컴파일러보다 더 많은 정보를 바탕으로 컴파일을 하고 더 나은 최적화를 제공한다. (캐싱 기능)
티어드 컴파일(tiered compilation)을 이용하면 코드는 먼저 클라이언트 컴파일러로 컴파일 되고 많이 쓰이게 되면 역최적화 후 서버 컴파일러로 재컴파일 된다. 자바 8에서는 기본으로 사용할 수 있다.
가비지 컬렉터 GC
JAVA 프로세스가 동작하는 과정에서 불필요한 또는 더 이상 사용하지 않는 객체들을 메모리에서 지우는 작업을 한다.
메모리 영역을 나눠서 오래 되었다고 분류되는 객체들중에서 사용되지 않는 객체들을 삭제하게 된다.
오래되었다는 기준은 임계값(Threshold)을 기준으로 판단된다.
JDK & JRE
- JRE 자바실행환경 (Java Runtime Environment) : JVM+클래스 라이브러리(Java API)
- JDK 자바개발도구 (Java Development Kit) : JRE+개발에 필요한 실행파일
- SDK (Software Development Kit)
참고한 링크들
https://shrtorznzl.tistory.com/82
http://www.tcpschool.com/java/java_intro_programming
https://jeongjin984.github.io/posts/JVM/
https://jaehoney.tistory.com/173
https://www.geeksforgeeks.org/what-are-the-roles-of-java-compiler-and-interpreter/?ref=gcse
https://www.geeksforgeeks.org/just-in-time-compiler/?ref=rp
https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html
https://minzoovv.dev/java/java-terminology/
https://velog.io/@youngerjesus/%EC%9E%90%EB%B0%94-JIT-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC