본문 바로가기
spring

내가 작성한 자바 코드는 어떻게 실행되는 것일까?(JVM)

by look-sun 2021. 3. 25.

백기선님의 스터디 중 1주차 과제이다. github.com/whiteship/live-study/issues/1

 

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. · Issue #1 · whiteship/live-study

목표 자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기. 학습할 것 JVM이란 무엇인가 컴파일 하는 방법 실행하는 방법 바이트코드란 무엇인가 JIT 컴파일러란 무엇이며 어떻게 동작하는지 JV

github.com

목표 : 자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.

학습할 것 :

  • JVM이란 무엇인가?
  • 컴파일은 어떻게 하는가?
  • 실행은 어떻게 하는가?
  • 바이트코드란 무엇인가?
  • JIT 컴파일러는 무엇이고, 어떻게 동작하는가?
  • JVM의 구성요소에는 어떠한 것들이 있는가?
  • JDK와 JRE의 차이는?

JVM이란 무엇인가?

JVM은 Java Virtual Machine, 자바 가상 머신의 약자로 바이트코드로 컴파일 된 코드를 실행시키는 가상머신입니다.

이름에서부터 느껴지듯이 프로그램이 가상머신에서 독립적으로 실행되기 때문에 JVM이 실행 가능한 곳이라면 어디에서든지 사용 가능합니다 또한 가상머신에서 실행되기 때문에 하드웨어에 직접적으로 접근하는 것은 불가능합니다.

애플리케이션은 어떤 위치에 있을까?

JVM에는 기본적인 기능 2가지가 있습니다.

  • 자바 프로그램이 어디에서나 실행 가능하게 하는 것
  • 프로그램의 메모를 알아서 관리하고 최적화 시키는 것

'한 번 작성해, 어디에서나 실행한다.'라는 문구가 한 번에 JVM의 필요성을 이해시켜주지 않나요?


컴파일은 어떻게 하는가?

C언어나 C++에서의 컴파일은 직접 기계어로 변환되는 것을 뜻하는 반면에 자바에서의 컴파일은 '바이트코드'라는 것으로 변환되는 것을 뜻합니다. 위에서 말했듯이 이 바이트코드를 JVM이 실행시킵니다.

자바의 컴파일은 .java 확장자를 가진 파일을 javac에 넣어 돌리면 .class 확장자를 가진 바이트 코드가 나오는 식입니다.

.java to .class used javac


실행은 어떻게 하는가?

이제 JVM과 javac의 역할에 대해서 우리가 배운것을 사용할 때가 되었습니다. java 코드를 짠 다음 javac로 컴파일 하여 바이트 코드를 만들고,

java {{프로그램명.class}}

라는 명령어로 실행시켜줍니다. 그럼 실행이 될꺼에요!!


바이트코드란 무엇인가?

바이트 코드는 위에서 얼핏 보셨다시피 javac라는 프로그램으로 컴파일되어 나오고, JVM에서 실행시키는 코드입니다.

위키백과를 보니 바이트코드의 정의는 '특정 하드웨어가 아닌 가상환경에서 실행하는 프로그램을 위한 이진 표현법이다. 하드웨어가 아닌 가상환경이라는 소프트웨어에 의해서 처리되기 때문에 보통 기계어보다 더 추상적이다.' 라고 합니다.

(javac로 컴파일해서 나온 바이트코드는 컴퓨터가 읽을 수는 없는 반기계어입니다. 굳이 반기계어를 해석하고, 코드를 짜는 사람은 없겠죠..? ㅋㅋ)


JIT 컴파일러는 무엇이고, 어떻게 동작하는가?

컴퓨터 프로그램을 만들때에 인터프리터 방식과 정적 컴파일 방식, 둘 중에 하나를 사용하는 것이 일반적입니다.

인터프리터는 프로그램 실행중 그때 그때 기계어로 변환하는 방식입니다. (쉽게 설명하자면 영어책을 읽으면서 그때그때 사전을 찾아가며 읽는다는 말과 비슷하다.) 그렇기 때문에 느릴 수 밖에 없습니다.

정적 컴파일 방식은 파일을 컴파일 한 후 프로그램을 실행하기 때문에 컴파일 하는데 시간이 조금 걸리는 반면, 프로그램을 실행시킬 때에는 가장 빠르다.

JIT 컴파일러는 둘을 섞어 놓았다고 보면 됩니다. 프로그램이 실행될 때 인터프리터 방식으로 기계어 코드를 생성하고, 같은 코드가 반복될 때에는 기계어를 캐싱(빠르게 꺼내서 볼 수 있게 메모리에 저장)하여 같은 코드를 기계어로 여러번 변환하는 일을 방지해줍니다.

JIT 컴파일을 사용하는 것중 대표적인 것으로는 JVM과 node.js와 .NET이 있습니다.


JVM의 구성요소에는 어떠한 것들이 있는가?

JVM의 구성요소에는 이러한 것들이 있습니다

  1. 클래스 로더
  2. 인터프리터
  3. 가비지 컬렉터
  4. 실행엔진

클래스 로더는 우리가 만든 .class 확장자를 가진 파일을 읽는 역할을 합니다. 클래스 로더의 구조는 이러합니다.

인터프리터는 python말할 때 가장 많이 나오는데요, 자바에서의 인터프리터는 바이트코드를 컴퓨터(머신)에 맞는 언어로 변환시켜주는 역할을 합니다. 인터프리터의 장점은 첫 번째 플렛폼에 종속되지 않는다. 두 번째 컴퓨터와 프로그램 사이에서 별도의 버퍼 역할을 한다.

실행엔진은 클래스 로더에 존재하는 클래스를 읽으면서 static이 붙어있는지 없는지를 판단합니다. 만약에 static이 붙은 클래스가 없다면 Java는 그대로 종료됩니다.

C/C++ 에서는 메모리를 직접 관리해야합니다. 하지만 Java에서는 가비지 컬렉터(GC)가 그 일을 대신해줍니다.


JDK와 JRE의 차이는?

JDK는 'Java Developer Kit'의 약자로 '자바 개발자 도구'라고 변역할 수 있습니다.

JDK는 자바 개발자를 위한 도구 모음집으로써 당연히 필요한 JRE를 포함하고 그 외에도 다른 도구들이 있습니다.

JRE는 'Java Runtime Environment'의 약자로 '자바 런타임 환경'이라고 번역할 수 있습니다.

JRE는 자바를 실행하는데 필요한 환경을 구축해둔 것 이라고 생각하시면 됩니다.


지금까지 JAVA의 구조에 대해 알아보았습니다.

이렇게 블로그를 써보는 것은 처음인데, 왜 기술블로그 기술블로그 하는지 알겠군요.

오늘 적어둔 내용은 절대 잊지 않도록 해야겠습니다.

자바 실행 순서 구조


이분들 정말 정리 잘 해놓으셨더라구요 참고하세요. (출처이기도 함)

댓글