들어가며
이번 포스트 에서는 자바가 동작하는 구동 과정의 대해 정리해 보려고 합니다. 자바가 매력적인 이유 중 하나인 구동 과정에 대한 이야기는 매우 흥미롭습니다.
자바는 어떻게 보여지나
제가 정리하면 이미지를 보시면 크게 3가지의 소프트웨어를 통해 동작한다는 것을 볼 수 있습니다.
JDK = 개발도구 , JRE = JVM용 OS , JVM = 자바 전용 가상 컴퓨터
이전 포스트에서 자바가 나온 이유에 대해 설명하며 다양한 플렛폼에서 사용이 가능하다는 의미가 바로 이런식으로 동작하기 때문에 가능합니다.
이런 특성을 Write once Run Anywhere 이라고 하는데 한국어로 “한번 쓰면 계속 쓸 수 있음” 입니다.
JVM의 특징을 정리해보면 다음 과 같습니다.
- 플랫폼 독립성: JVM은 플랫폼 독립적입니다. 즉, Java 프로그램은 한 번 작성되면 어떤 플랫폼에서도 실행될 수 있습니다. 이는 Java 언어가 컴파일된 바이트코드를 JVM이 해석하고 실행하기 때문에 가능합니다.
- 자동 메모리 관리: JVM은 가비지 컬렉션을 통해 메모리를 자동으로 관리합니다. 이는 프로그래머가 명시적으로 메모리 할당과 해제를 관리할 필요가 없게 해줍니다. 따라서 Java 프로그램에서 메모리 누수 및 다른 메모리 관련 오류를 방지할 수 있습니다.
- 보안: JVM은 강력한 보안 기능을 제공합니다. Java 애플리케이션은 샌드박스 환경에서 실행되어 악의적인 코드의 실행을 방지합니다. 또한 JVM은 바이트코드 검증과 같은 보안 기능을 내장하고 있어 안전한 실행을 보장합니다.
- 성능 최적화: JVM은 Just-In-Time (JIT) 컴파일러를 사용하여 프로그램의 성능을 최적화합니다. JIT 컴파일러는 프로그램이 실행될 때 바이트코드를 네이티브 코드로 변환하여 실행 속도를 향상시킵니다.
- 동적 로딩: JVM은 클래스 파일을 동적으로 로드하여 실행할 수 있습니다. 이는 애플리케이션의 유연성을 높이고, 프로그램의 실행 중에도 새로운 클래스를 동적으로 로드하여 실행할 수 있게 합니다.
- 멀티스레딩 지원: JVM은 멀티스레드를 지원하여 동시에 여러 작업을 수행할 수 있습니다. 이는 Java 프로그램이 병렬 및 동시성 작업을 수행하는 데 도움이 됩니다.
- 풍부한 표준 라이브러리: JVM은 Java 표준 라이브러리 (Java API)를 제공하여 다양한 작업을 수행하는 데 필요한 클래스와 메서드를 제공합니다. 이러한 표준 라이브러리는 개발 과정을 단순화하고 생산성을 향상시킵니다.
읽다 보면 생각보다 처음보는 단어들도 보입니다.
컴파일된 바이트코드
우리가 작성한 코드는 고수준 프로그래밍 언어로 작성된 “소스코드” 라고부릅니다.
위 사진에서 가장 처음에 시작하는 부분입니다.
그리고 이것을 자바 번역기가 중간형태의 이진코드로 변환시킵니다.
여기서 자바 번역기는 자바 컴파일러를 의미 합니다.
그리고 이런 이진코드의 파일을 .class 라는 바이너리형식으로 저장합니다.
이런 class파일을 컴파일된 바이트코드라고 합니다.
그리고 이러한 class 파일을 JVM의 인터프리터 or JIT(just in time)컴파일러에 의해 실행됩니다.
인터프리터? JIT?
인터프리터는 생각보다 가까운 개념입니다.
고수준 언어로 작성된 프로그램을 한 줄씩 읽고 해석하여 실행하는 프로그램입니다.
이는 컴파일러와 대비되는 개념으로, 컴파일러가 전체 소스 코드를 기계어로 번역한 후 실행하는 것과는 다릅니다.
즉, 전체코드를 읽는 컴파일러 보다 빠른 속도로 프로그램을 실행시킬 수 있습니다.
대표로 Python , javaScript 가 사용하고 있습니다.
그리고 이런 언어들은 스크립트 언어라고 부릅니다.
이런 언어들은 컴파일 과정 즉, 기계어를 생성하는 과정을 스킵 하고 바로 메모리에 적재하기 시작합니다. 물론 이런 과정이 불안하기 때문에 각 언어마다 해결법들을 만들었는데 관련 포스트를 적으면 정리해보겠습니다.
최근 웹에서도 Flask , Django 가 선호되고 Node js , 혹은 프론트엔드에서도 많이 사용되는 이유입니다.
당연히 Java와 같은 언어들에 비해서 성능도 안정성도 떨어집니다.
Python을 다루어 보면 실행 시작에서는 오류를 내지 않아도 올라가서 실행하다 보면 오류가 나는 경우가 많은 것처럼 강력한 검사를 하지 않기 때문입니다.
최근 트렌드에 대한 생각
하지만 개인적인 생각은 최근에는 관련 언어들의 발전이 계속 이루어지고
대규모 시스템 구축을 하거나 정부 과제를 수행하지 않는 업체들에서는 이런 가벼운 언어로 빠르게 개발하고 레거시 하는 과정을 더욱 선호 하는 거로 보입니다.
취업정보 사이트에 들어가 보면 생각보다 Node.js나 Python 개발자들을 많이 뽑는게 그런 이유여서 라고 생각합니다.
특히 , 최근 트랜드인 MSA - 마이크로 서비스 아키텍처에서는 작은 어플리케이션을 여러개 만들어서 논리적으로 이어놓는것을 추구하고 있기 때문이기도 한 것 같습니다.
JIT (Just in Time)
- 바이트코드 해석: JVM(Java Virtual Machine)은 바이트코드를 인터프리터를 사용하여 한 줄씩 해석하고 실행합니다.
- 실행 주기 모니터링: JVM은 프로그램의 실행 중에 어떤 부분이 자주 실행되는지 모니터링합니다.
- 컴파일 결정: JIT 컴파일러는 실행 주기 모니터링을 기반으로 하여 자주 실행되는 부분이나 코드 루프 등을 선택하여 컴파일할지 결정합니다.
- 컴파일: JIT 컴파일러는 선택된 부분을 기계어로 변환하여 네이티브 코드로 생성합니다.
- 캐시 및 재사용: 생성된 네이티브 코드는 캐시에 저장되어 이후에 동일한 부분이 실행될 때 재사용됩니다.
JIT 는 이런식으로 동작합니다.
해석 → 자주 나타나는 부분 분석 → 컴파일 결정 → 기계어 생성 → 기계어를 캐시에 저장해두기
여기서 인터프리터를 사용하는 과정이 나옵니다.
그리고 이러한 JIT는 장점이 있는데 정리하면 다음과 같습니다.
- 실행 시간 최적화: JIT 컴파일러는 실행 중에 프로그램의 성능을 분석하고 최적화할 수 있습니다. 이는 실행 시간에 최적화된 코드를 생성하여 프로그램의 실행 속도를 향상시킵니다.
- 메모리 사용량 최적화: JIT 컴파일러는 프로그램의 실행 중에 필요한 부분만 컴파일하고 메모리에 저장합니다. 따라서 불필요한 코드를 메모리에 로드하지 않아 메모리 사용량을 최적화할 수 있습니다.
- 플랫폼 독립성 유지: JIT 컴파일러는 바이트코드를 실행 중에 네이티브 코드로 변환하기 때문에, 플랫폼 독립성을 유지하면서도 실행 시간에 최적화된 코드를 생성할 수 있습니다.
참 재미있는 방식입니다. 지금 이 순간의 최적의 방법을 찾아 시간과 메모리를 최적화 시키는 방법은 자바를 더욱 매력적인 언어로 만든 장점이라고 보입니다.
정리하며
이번 포스트에서는 자바의 구동과정에 대해 정리해 봤습니다.
“JVM은 가비지 컬렉션을 통해 메모리를 자동으로 관리합니다.”
이부분을 보면 가비지 컬렉션이 뭐지? 라고생각해볼 수 있습니다. 그래서 다음 포스트 에서는
자바가 메모리를 사용하는 이야기를 하며 가비지 컬렉션에 대한 이야기도 함께 해보겠습니다.
'JAVA' 카테고리의 다른 글
JAVA-OverLoding & OverRiding (0) | 2024.05.29 |
---|---|
JAVA-스레드 (0) | 2024.05.28 |
JAVA- 메모리 (0) | 2024.05.28 |
JAVA -객체 와 동작 (0) | 2024.05.27 |
JAVA - 소개 (0) | 2024.05.27 |