[Java] - JVM : JavaVirtualMachine

uHan2·2020년 11월 18일
2

todayilearned.Java

목록 보기
2/6

안녕하세요.
지금까지 계속 저만의 기술 블로그를 만들어야지, 만들거야
마음으로만 다짐하다가 인제야 시작하게 되었습니다.
비록 시작은 코딩일기지만, 그 끝은 창대하게
어엿한 개발자 블로그로 성장할 수 있도록 노력하겠습니다.


1주차 과제 :
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가

해당 게시글은 백기선님의 Java live-study 의 과제 내용을 정리한 글입니다.

JVM이란 무엇인가

  • 전반적으로 이해하기 좋은 그림이 있어 참고하였다. 그림 출처

  • JVM은 JavaVirtualMachine의 머리글자 이다.

  • 이 JVM은 Windows OS, mac OS 등 각각의 운영체제에 맞게 구현되어 있고
    자바 바이트 코드를 실행하는 주체이다.

  • Java의 철학은 Write Once Run Anywhere(WORA)이다. 이는
    말그대로 운영체제, 플랫폼에 종속적이지 않고 한 번 작성한 코드는 어디서든 작동 될 수 있는 것을 목표로 한다. 그래서 Java는 운영체제에 종속적이지 않다 고 하는데 이 말은 맞다. 하지만 Java는 JVM에 종속적이다.

  • 이 외에도 클래스, 스택, 힙 등으로 이루어진 메모리 요소힙 영역에서 매우 큰 역할을 맡고 있는 Garbage Collector 등 JVM은 Java를 다른 언어와 다른 차별점을 주는 중요한 만큼 파면 팔수록 내용이 굉장히 많다.
    우선 이 과제에서는 JVM의 개괄 정도만 정리하고 후에 또 JVM의 상세한 포스트를 작성해야겠다.

컴파일 하는 방법

  • 사실 자바프로그래밍을 처음 접했을때 IDE를 활용해서 개발하는 것으로 먼저 시작했다.
    그래서 javac 를 이용해서 컴파일 하는 방식은 시간이 좀 지나고 나서야 알게 되었다.

  • 후에 기술할 JDK를 설치하면 그 안에 .java파일을 컴파일할 수 있는 javac가 포함되어 있다.
    cmd 나 terminl 등에서 javac 명령어로 .java파일을 컴파일할 수 있다.

  • 아래 화면처럼 HelloWorldTest.java 파일이 있는 경로에 가서
    javac HelloWorldTest.java 를 치면 컴파일이 되어
    HelloWorldTest.class 파일이 생성된다.
    위에 기술한 JVM이 바로 이 파일명.class 파일을 실행하는 것이다.

  • 이처럼 커피잔 아이콘의 HelloWorldTest.class 파일이 생성 되었음을 확인할 수 있다!

  • 사실 javac에는 매우 많은 명령어가 있다 .. 하지만 사실 이렇게 터미널로 javac를 이용하지 않고 툴에 의존해와서 거의 모른다 .. 시간내서 한번 어떠한 옵션들이 있는지 살펴보아야겠다.

실행하는 방법

  • 위에서 컴파일할때는 javac 명령어를 사용했다면 실행할땐 java명령어를 사용하면 된다.

  • java 명령어 또한 옵션이 매우 많다 .. 이것도 시간내서 찾아봐야겠다.

바이트코드란 무엇인가

  • 우리가 .java 파일을 문법에 맞게 작성하였다 하더라도 컴퓨터는 이 파일을 바로 읽고 수행할 수 없다. 컴퓨터는 결국 0과 1밖에 모르기 때문에 변환과정이 필요하다.
    윗 단락에서 확인했듯이 우리가 작성한 .java 파일은 JVM이 이해할 수 있는 .class 파일로 변환이 되며 바로 이 .class 파일이 바이트코드 이다.

JIT 컴파일러란 무엇이며 어떻게 동작하는지

  • JITJust In Time의 머리글자이다. 이 JIT은 후에 기술할 JRE안에 포함되어있다.

  • 자바는 .java 파일을 .class 파일로 변환하고(compile) 변한된 .class 파일은 기계어로 변환되어야(interpret) 하는데 이때의 cost가 높기 때문에 JIT이 탄생하기 전의 Java는 사용이 힘들정도로 상당히 느렸다고 한다. 하지만 JIT 컴파일러의 등장으로 속도가 느리다는 문제가 해결이 되었다.

  • 흔히 컴파일 이라고 하는 것에는 인터프리트 방식정적 컴파일 방식 두 종류가 있다. 인터프리트 방식은 예를 들면 Python이 있는데 실행 중에 코드를 읽어가면서 기계어 코드로 변환하는 방식이고 정적 컴파일 방식은 실행 전에 전체 코드를 기계어로 변환하는 방식이다.

  • JIT 컴파일러는 인터프리트 방식과 정적 컴파일 방식 두 가지를 혼합한 방식인데 우선 프로그램의 런타임 때 자주 쓰이는 코드(메소드)를 기계어 코드로 변환하고 캐싱한다. 이후에 해당 메소드가 또 사용될때 캐싱해둔 코드를 사용한다.

  • 현재 우리가 사용하는 JVM 일반적으로 Hotspot JVM 이라고 한다. 그리고 이 JIT은 Hotspot JVM의 핵심 컴파일러 라고 한다. Hotspot 이란 사용이 되는 hotspot에 는 JIT 컴파일러를 사용하는 방식이라고 한다.
    ( 미국의 Longview Technologies LLC라는 회사에서 1999년에 처음 발표한 JVM이다. 이후 SUN에 인수되었으며, 1.2버전부터 SUN의 기본적인 JVM이 되었다고 한다. 출처)
    이 Hotspot JVM의 핵심 컴파일 방법 중의 하나라고 한다.

  • 자주 쓰이는 메소드인지는 어떻게 아냐 이 부분이 궁금해서 찾아보니 JVM에서 정해놓은 임계값을 넘으면 그때 JIT 컴파일러를 호출 한다고 한다 ..
    (사실 느낌만 오고 온전히 이해는 못했다)
    그래서 JVM 옵션을 활용하여 JIT 컴파일러를 튜닝할 수 있다고 한다 ..
    하지만 이렇게까지 깊이 있게는 시도하지 못하겠다 ..

  • JIT 은 자바의 성능을 끌어올려준 큰 역할을 담당하는 만큼 코드 최적화 단계 및 방법 등 찾아보면 볼수록 내용이 굉장히 깊다. 하지만 중요한만큼 나중에라도 꼭 다시 제대로 봐야겠다.

  • JIT 컴파일러의 경우 자바를 공부할때는 전혀 들어보지 못했다 ..
    심지어 비교적 최근데 알게되었는데 학교에서 [컴퓨터시스템구조] 라는 과목을 듣다가 알게되었다.

JVM 구성 요소

  • 시각화를 위해 사진자료를 첨부하였다.
    그림 출처

  • JVM 은 크게 네 가지로 구성 되어있다.

    • Class Loader
      .java 파일을 변환한 .class 파일(바이트코드)를 Runtime Data Area에 적재한다.
    • Execution Engine
      상기에 기술한 JIT 컴파일러가 여기에 있으며 적재된 클래스들을 기계어 코드로 변환하여 실행한다.

    • Garbage Collector
      JVM이 제공하는 편리한 기능 중 하나이다. 자바는 할당한 메모리에 대해서 추가적인 관리를 해줄 필요가 없는데 그 이유가 바로 Garbage Collector (GC) 덕분이다. 더 이상 특정 메모리가 참조되지 않는다고 판단하면 GC가 자동으로 그 메모리를 해제하여 정리해준다.

    • Runtime Data Area
      JVM의 메모리 영역으로 그림과 같이 구성되어있다.

      • Method Area
        멤버 변수, 메소드 정보, static 및 final 변수, Type 정보 등이 여기에 저장된다.

      • Heap Area
        동적으로 생성된 오브젝트나 컬렉션, 배열 등이 존재하는 곳이며 GC가 관리하는 대상이다.

      • Stack Area
        지역 변수나 파라미터 등이 저장되는 곳이며 동적으로 생성된 객체의 레퍼런스는 여기에 저장된다. Stack은 스레드별로 독자적으로 가진다. Heap에 있는 오브젝트의 레퍼런스가 Stack에 없는 경우 GC의 관리 대상이 되어 정리된다.

      • PC register
        현재 쓰레드에서 실행되고 있는 부분의 주소와 명령을 저장한다.

      • Native Method Stack
        자바 외의 언어로 작성된 Native 코드를 위한 메모리 영역

  • JVM을 대략적으로만 알았지 이렇게 내부 구조를 상세하게 찾아본적은 이번이 처음이다 .. 내용 참조 해당 글에서 상당 부분을 참조하였다 ..
    이 부분도 나중에 시간을 내서 천천히 읽어봐야하겠다.

JDK와 JRE의 차이

  • JDK : Java Development Kit
    해석하자면 "자바 개발 키트" 이다. 자바언어를 이용한 개발을 할때 필요한 키트를 포함하고 있다. JRE를 포함하고 있으며 javac 나 javadoc, jdb 등 을 추가로 갖고 있다.
  • JRE : Java Runtime Environment
    해석하자면 "자바 실행 환경" 이다. 자바로 만들어진 프로그램을 실행하기 위해서는 JRE를 필수로 설치해야 한다.
    JRE를 포함하여 배포된 프로그램의 경우에는 JRE를 별도로 설치하지 않아도 실행이 가능하긴 하다.

  • 사실 이 둘의 비교는 그림으로 보는게 이해하기 좋다.
    그림 출처

  • 원래는 JDK 안에 JRE가 포함되어 제공이 되었는데 jdk 11 버전부터는 포함되지 않는다고 한다. jlink를 이용해서 개발자들이 애플리케이션을 개발할 때 애플리케이션에 링크를 걸어서 JRE를 번들로 포함시키길 바라기 때문이라고 한다.
    그림 및 내용 출처

마치며

그동안 자바를 공부한답시고 알고리즘 문제풀이 혹은 개발하는 데에만 초점을 맞췄다는 것을 뼈저리게 느끼는 시간이었다. 그렇게 생각없이 써오던 언어와 플랫폼의 기저에는 중요한 개념들이 상당히 많다는 것을 제대로 느꼈고 앞으로는 단순히 개발, 기술 공부 뿐 아니라 이렇게 기반을 이루고 있는 개념들에 대해서도 정리하는 시간을 갖도록 하겠다!

참고

https://jhnyang.tistory.com/224
https://velog.io/@aki/HotSpot-JVM
https://jeong-pro.tistory.com/148
http://java-awsome.blogspot.com/2017/07/what-is-jit-compiler-in-java.html
https://velog.io/@litien/JVM-%EA%B5%AC%EC%A1%B0
https://12bme.tistory.com/382
https://medium.com/@lazysoul/jit-just-in-time-16bb63f3ae26
https://medium.com/@ahn428/java-jit-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-c7d068e29f45

profile
For the 1% inspiration.

0개의 댓글