Java/자바의 신 VOL.2
01. 이쯤에서 자바의 역사와 JVM에 대해서 알아보자
h2boom
2024. 6. 26. 22:13
자바의 역사
- 제임스 고슬링에 의해 만들어졌다.
- 자바 언어의 모토는 "Write Once, Run Anywhere (WORA)"
- 자바는 HP 및 IBM에서 만드는 JDK와 Orcle에서 만드는 JDK가 있다.
- HP 및 IBM은 별도의 OS를 갖고 있어 그 OS에 최적화 된 JDK를 개발해 사용하고 있다.
- 리눅스의 경우 Oracle의 JDK를 주로 사용한다.
- 어떤 OS에서 개발하든 JDK 버전만 맞으면 적용할 OS에서 컴파일하면 실행에 문제가 없다.
- Oracle JDK로 개발하고 HP의 JDK로 컴파일하더라도 문제가 없다.
- JDK는 JRockit와 오픈소스 버전의 OpenJDK로 나뉜다.
JDK : Java Development Kit
JRE : Java Runtime Environment (실행만을 위한 환경으로 컴파일 등 각종 프로그램이 제외된 상태)
- 자바 언어의 다섯 가지 특징
- it should be "simple, object-oriented and familiar"
- 자바는 "단순하고 객체지향이며 친숙"해야 한다.
- 기본 컨셉을 배우는 게 어렵지 않고 수 많은 프레임워크들이 있다.
- 자바를 처음 개발할 때부터 객체지향으로 디자인 되어있어서 객체지향 특징들을 지원할 수 있는 구조다.
- 개발하면서 필요한 여러 기능들을 API를 통해 제공하고 있다.
- 파일을 읽고 쓰기 위한 라이브러리
- 네트워크로 데이터를 주고받는 I/O 관련 라이브러리
- 그래픽 UI 등을 개발하기 위한 라이브러리...
- 자바는 "단순하고 객체지향이며 친숙"해야 한다.
- it should be "robust and secure"
- 자바는 "견고하고 보안상 안전"해야 한다.
- 자바는 컴파일 / 실행할 때 문법적 오류에 대해 체크한다.
- 메모리 관리 모델이 매우 단순하다.
- 분산 환경에서 사용하기 위해 디자인됐다.
- 자바는 "견고하고 보안상 안전"해야 한다.
- it should be "architecture-neutral and portable"
- 자바는 "아키텍처에 중립적이어야 하며 포터블"해야 한다.
- 자바는 아키텍처에 중립적인 바이트 코드를 생성한다.
- 자바 버전만 동일하다면 동일한 프로그램은 어떤 플랫폼에서도 실행할 수 있다.
- 기본 데이터 타입의 크기를 지정하고 숫자 연산자에 대한 행위들을 정의해 두었다.
- 자바 프로그램은 어떤 플랫폼에서도 동일한 결과가 나오고 하드웨어와 소프트웨어 아키텍처에 따른 데이터 타입의 호환성에 문제가 발생하지 않는다.
- JVM 덕분에 호환성과 포터블한 환경을 제공할 수 있다.
- 자바는 아키텍처에 중립적인 바이트 코드를 생성한다.
- 자바는 "아키텍처에 중립적이어야 하며 포터블"해야 한다.
- it should excute with "high performance"
- 자바는 "높은 성능"을 제공해야한다.
- 자동화된 가비지 컬렉터가 낮은 우선 순위의 쓰레드를 처리하기 때문에 보다 높은 성능을 낼 수 있다.
- 빠른 성능을 내기 위해 네이티브한 언어로 작성한 부분을 자바에서 사용할 수 있도록 되어있다.
- 자바는 "높은 성능"을 제공해야한다.
- it should be "interpreted, threaded, and dynamic"
- 자바는 "인터프리터 언어이며, 쓰레드를 제공하고, 동적인 언어"여야 한다.
- 자바 인터프리터는 바이트 코드를 어떤 장비에서도 수행할 수 있도록 한다.
- 기존 무거운 컴파일과 링크, 테스트 사이클을 거쳐야하는 개발 환경보다 빠른 환경을 구축할 수 있다.
- 자바는 멀티 쓰레드 환경을 제공해 동시에 여러 작업을 수행할 수 있다.
- 컴파일러는 매우 엄격한 정적인 점검을 수행하며 실행 시 동적으로 필요한 프로그램을 링크시킨다.
- 자바는 "인터프리터 언어이며, 쓰레드를 제공하고, 동적인 언어"여야 한다.
- it should be "simple, object-oriented and familiar"
JIT 컴파일러
- Just-In-Time의 약자로 동적 변환이라고 생각하면 된다.
- 프로그램 실행을 보다 빠르게 하기 위해서 만들어졌으며 명칭은 컴파일러지만 실행 시에 적용되는 기술이다.
- 역사적으로 컴퓨터 프로그램을 실행하는 방식은 두 가지가 존재했다.
- 인터프리트 방식 : 프로그램을 실행할 때마다 컴퓨터가 알아 들을 수 있는 언어로 변환하는 작업을 수행하는 방식으로 속도가 매우 느리다.
- 정적(static) 컴파일 방식 : 실행하기 전에 컴퓨터가 알아 들을 수 있는 언어로 변환하는 작업을 미리 실행하는 방식으로 변환 작업은 딱 한 번만 수행한다.
- JIT는 이 두 가지 방식을 혼합한 방식이다.
- 변환 작업은 인터프리터에 의해 지속적으로 수행되지만, 필요한 코드의 정보는 캐시에 담아두었다가(메모리에 올려두었다가) 재사용하게 된다.
- 자바 프로그램이 수행되는 절차
- 자바 소스 코드 ㅡ> 자바 컴파일러 ㅡ> 컴파일된 바이트 코드(.class) ㅡ> JVM ㅡ> 기계 코드 ㅡ> 하드웨어 및 OS
- javac 명령어를 수행하는 것은 텍스트로 만든 java파일을 어떤 OS에서도 수행될 수 있도록 바이트 코드라는 파일로 만드는 과정.
- JVM ㅡ> 기계 코드로 변환되는 부분을 JIT에서 수행한다.
- 자바 소스 코드 ㅡ> 자바 컴파일러 ㅡ> 컴파일된 바이트 코드(.class) ㅡ> JVM ㅡ> 기계 코드 ㅡ> 하드웨어 및 OS
- JIT 사용 시 반복적으로 수행되는 코드는 매우 빠른 속도로 수행하지만 처음 시작할 때는 변환 단계를 거쳐야하기 때문에 느리다는 단점이 있다.
HotSpot
- HotSpot 클라이언트 컴파일러
- 예전 CPU 코어가 하나였던 시절 그런 사용자를 위해서 만들어진 것으로 애플리케이션 시작 시간을 빠르게 하고 적은 메모리를 점유하도록 하는 것.
- HotSpot 서버 컴파일러
- 코어가 많은 장비에서 애플리케이션을 돌리기 위해서 만들어진 것으로 애플리케이션 수행 속도에 초점이 맞춰져있다.
JVM / GC
- JVM (Java Virtual Machine) : 자바 가상 머신으로 작성한 자바 프로그램이 수행되는 프로세스를 의미한다.
- 애플리케이션이 수행되면 JVM 위에서 애플리케이션이 동작한다.
- JVM에서 작성한 프로그램을 찾고 실행하는 일련의 작업이 진행된다.
- 가비지 컬렉터 (Garbage Collector) : JVM 내에서 메모리 관리를 자동으로 해주는 것을 가비지 컬렉터라고 한다.
- 가비지 컬렉터에 의해 사용하고 남아있는 전혀 필요 없는 객체들을 알아서 청소해준다.
- 가비지 컬렉터가 작업을 수행하는 것을 "GC가 발생했다", "가비지 컬렉션을 수행한다"라고 한다.
- 메모리가 알아서 청소가 된다하더라도 메모리를 효율적으로 사용해 개발하는 것은 중요하다.
- 어떤 객체를 생성하더라도 그 객체는 언젠가 쓰레기가 되어 메모리에서 지워져야만 한다.
- G1 (Garbage First)라는 가비지 컬렉터를 제외한 나머지 JVM은 사진과 같은 영역을 나누어 Heap 공간에 객체들을 관리한다.
- 가장 왼쪽에 있는 Young 영역은 젊은 객체들이, Old 영역은 늙은 객체들이 있다.
- Young 영역은 Eden과 Survivor 영역으로 나뉜다.
- Eden : 객체를 생성하자마자 저장되는 장소
- Survivor : Eden 영역이 꽉차면 살아있는 객체가 이동되는 장소, 영역은 두 개지만 한 곳은 반드시 비어있어야한다.
- 마이너(Minor) GC (Garbage Collection) / 영(Young) GC 가 발생하는 순서
- 1. Eden 영역에 객체 생성
2. Eden이 꽉차면 Survivor 영역으로 살아있는 객체만 복사되어 이동되고 다시 Eden 영역을 채운다
3. Survivor 영역이 꽉 차면 다른 Survivor 영역으로 객체가 복사되는데 Survivor 영역은 두 개지만 하나는 무조건 비어 있어야 하기에 Eden이 꽉차면 객체가 들어있는 Survivor로 이동한다. - 메이저(Major) GC / 풀(Full) GC
- Young 영역에서 오래 살아있는 객체들은 Old 영역으로 이동한다.
- Old 영역이 꽉차면 GC가 발생하는데 이것을 major GC, full GC라고 한다.
- Perm 영역에는 클래스나 메소드에 대한 정보가 쌓인다.
- Young GC가 Full GC보다 빠르고 더 적은 공간이 할당되며 객체들을 처리하는 방식이 서로 다르다.
- Oracle JDK에서 제공하는 GC 방식
- Serial GC
- Parallel Young Generation Collector
- Parallel Old Generation Collector
- Concurrent Mark & Sweep Collector (CMS)
- Shenandoah GC
- ZGC
- Garbage First (G1)
- WAS로 사용하는 JVM에서 사용하면 안되는 것은 Serial GC
- 클라이언트 용 장비에 최적화 된 GC이기 때문에 WAS에서 사용하면 GC 속도개 마우 느려 웹 애플리케이션이 엄청 느려진다.
- Young 영역은 Eden과 Survivor 영역으로 나뉜다.
- 가장 왼쪽에 있는 Young 영역은 젊은 객체들이, Old 영역은 늙은 객체들이 있다.