티스토리 뷰

JVM이란 무엇인가

Java Virtual Machine : 자바를 실행하기 위한 가상 컴퓨터

스크린샷 2021-12-14 오후 5 32 31

The Java™ Tutorials

자바로 작성된 애플리케이션은 이 가상 컴퓨터(JVM)위에서만 실행된다.

  • 장점
    • Java application이 OS, 하드웨어에 독립적이기 때문에, OS와 하드웨어가 달라지더라도 Java application code를 변경할 필요가 없음
  • 단점
    • JVM을 거쳐서 실행되기 때문에 속도가 느림. -> JIT 컴파일러와 최적화 기술로 속도 저하 문제를 해결.

 


 

컴파일 하는 방법 & 실행하는 방법

  1. java 프로그램 작성 ( Main.java )
  2. 컴파일
    javac Main.java
    결과 : Main.class 파일 생성 (bytecode, executable file)
  3. run
    java Main
    결과 : 작성한 자바 프로그램이 실행됨

스크린샷 2021-12-16 오후 3 50 28

https://www.youtube.com/watch?v=gHXzyAkbUhk

스크린샷 2021-12-16 오후 3 21 40

https://www.youtube.com/watch?v=gHXzyAkbUhk

jar 파일

  • Java Archive
  • compile 된 java project를 압축한 파일
  • .class files + metadata + other resources
  • 사용목적
    • 다른 프로젝트에 java code나 library를 distribute 하기 위해 사용.
    • IDE 없이 자바 프로그램을 실행하기 위해 사용
  • 분류
    • executable jar file
      • jar file 내부
        • /META-INF/MANIFEST.MF : main 클래스 명시(시작점)
      • compile
        java -jar JarExample.jar arg1 arg2
    • non-executable jar
      • /META-INF/MANIFEST.MF 부재
      • compile
        java -cp JarExample2.jar com.baeldung.jarArguments.JarExample arg1 arg2
      • 시작 클래스를 option으로 명시

Run a Java Application from the Command Line | Baeldung

스크린샷 2021-12-16 오후 6 51 25

 

(참고) resource files in jar
icon 이나 user가 사용하는 data file(images) 은 jar 파일에 함께 넣는 것이 좋다. -> Class 나 ClassLoader 의 getResouce() 메소드로 추출 가능
그러나 configuration 파일의 경우, 배포 과정에 따라 달라질 수 있으므로 jar 파일에 넣지 않는 것이 낫다. -> jar file을 실행할 때 argument로 config 파일의 path를 넘겨주는 방식을 일반적으로 사용.

 


 

바이트코드란 무엇인가

  • 개발자가 작성한 자바 코드를 java compiler를 이용해 컴파일한 코드.
  • 간단히 Hello world 를 출력하는 프로그램을 작성했다. 그리고 javac 로 컴파일하니 .class 파일이 나왔다. .class 파일을 노트패드로 열어보면 다음과 같다.
  • cafe babe 0000 0037 001d 0a00 0600 0f09 0010 0011 0800 120a 0013 0014 0700 1507 0016 0100 063c 696e 6974 3e01 0003 2829 5601 0004 436f 6465 0100 0f4c 696e 654e 756d 6265 7254 6162 6c65 0100 046d 6169 6e01 0016 285b 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 2956 0100 0a53 6f75 7263 6546 696c 6501 000c 5765 6c63 6f6d 652e 6a61 7661 0c00 0700 0807 0017 0c00 1800 1901 000b 4865 6c6c 6f20 6a61 7661 2107 001a 0c00 1b00 1c01 0007 5765 6c63 6f6d 6501 0010 6a61 7661 2f6c 616e 672f 4f62 6a65 6374 0100 106a 6176 612f 6c61 6e67 2f53 7973 7465 6d01 0003 6f75 7401 0015 4c6a 6176 612f 696f 2f50 7269 6e74 5374 7265 616d 3b01 0013 6a61 7661 2f69 6f2f 5072 696e 7453 7472 6561 6d01 0007 7072 696e 746c 6e01 0015 284c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b29 5600 2100 0500 0600 0000 0000 0200 0100 0700 0800 0100 0900 0000 1d00 0100 0100 0000 052a b700 01b1 0000 0001 000a 0000 0006 0001 0000 0001 0009 000b 000c 0001 0009 0000 0025 0002 0001 0000 0009 b200 0212 03b6 0004 b100 0000 0100 0a00 0000 0a00 0200 0000 0300 0800 0400 0100 0d00 0000 0200 0e

 

(참고) 클래스 파일은 cafe babe 로 이루어진 4바이트로 시작된다. 이는 .class 파일임을 명시하기 위한 magic number다. A~F로 이루어져있고, 외우기 쉽기 때문에 이런 방식을 택했다고 한다.

 

Javap 를 이용하면 위 클래스 파일을, 역어셈블할 수 있다.
java -p {클래스이름}

스크린샷 2021-12-17 오후 12 00 39

바이트코드가 어셈블리와 유사하다는 것을 볼 수 있다.

바이트코드 특징

  • Byte-sized opcodes
    • only 256 possible opcodes
  • operand : 1 or 2 bytes -> instruction : 1~3 bytes
  • stack machine
    • operands를 stack에 넣어 두고, 연산의 결과도 stack에 담는 방식.
    • <-> register 를 사용하는 machine

YouTube
-> 오라클 개발자가 바이트코드 문법을 설명하는 영상. 어려워서 중도 포기…

위 바이트코드가 JVM 내부에 있는 인터프리터를 거쳐서 OS 가 읽을 수 있는 binary code로 변환된다.

 


 

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

  • 컴파일러 : 소스코드 -> 어셈블리 코드
  • 컴파일 과정
    • factorial.c -> Lexing -> Parsing -> Code generation -> Optimization -> factorial.out (Compile time)
    • Lexing & Parsing : String 을 모아서 자료구조로 변환하는 것 (?)
  • Compiled language 문제점
    • Compiler를 만드는 것이 어렵다.
    • Compilation이 느려질 수 있다. -> development cycle이 느려짐
    • CPU architecture에 의존적이다.
  • 인터프리터 :
  • 인터프리팅 과정
    • factorial.py -> Lexing -> Parsing -> Execute (Runtime)

스크린샷 2021-12-23 오후 4 40 47

https://www.youtube.com/watch?v=sQTOIkOMDIw

스크린샷 2021-12-23 오후 4 41 19

https://www.youtube.com/watch?v=sQTOIkOMDIw

- 장점
    - source code is portable. “Write once, run everywhere”
    - easy to write compared to Compiler
    - Compilation is faster than compiler (no code generation, optimization steps)
- 단점
    - Low Performance

스크린샷 2021-12-23 오후 4 56 21

https://www.youtube.com/watch?v=sQTOIkOMDIw

스크린샷 2021-12-23 오후 4 51 42

https://www.youtube.com/watch?v=sQTOIkOMDIw

스크린샷 2021-12-23 오후 4 51 50

https://www.youtube.com/watch?v=sQTOIkOMDIw

  • VM 도입 이후
    • Interpreter 만을 사용할 때보다 performance 향상
    • portable
    • performance 가 compiled version에 비하면 떨어짐.
    • optimization 이 생략되었기 떄문…
  • JIT
  1. 자주 쓰이는 코드를 찾는다.
  2. runtime에, 1번 코드를 machine code로 바꾼다.
  3. Machine code를 optimize
  4. 자주 쓰이는 코드를 optimize 된 machine code로 치환

스크린샷 2021-12-23 오후 5 04 00

https://www.youtube.com/watch?v=sQTOIkOMDIw

 

(참고) VM이 있기 때문에 어떤 code가 자주 사용되는 코드인지 식별 가능

 

  • JIT 이 해주는 Optimization
    • Expand function call
    • instruction scheduling
    • eliminate identical redundant expressions
    • eliminate dead code
    • etc
  • Tradeoffs
    • JIT Compilation is slow -> large initial delay
    • user webpage 등에서는 빠른 rendering을 위해 JIT Compile을 생략하는 것이 좋을 수 있음.
    • only use JIT for “HOT” code
  • Conclusion
    • Principle behind JIT
      • compile native code during runtime for hot sections
      • balance : startup time vs execution time
    • real world JITs are super complex

YouTube

 


 

JVM 구성 요소

스크린샷 2021-12-24 오후 6 36 34

https://www.youtube.com/watch?v=sQTOIkOMDIw

  • classLoader
    • loading phase
      • bootstrap loader : rt.jar (pre-compiled)
        e.g. System class
      • extension loader : /jre/lib/ext/ 에 있는 file 들을 메모리로 가져옴.
        e.g. OJDBC.jar
      • application loader : 사용자가 개발한 class file.
    • linking phase
      • verify : class file이 standard에 맞는지 체크
      • prepare : static variable 메모리 할당, default value로 세팅
      • resolve : symbolic reference -> actual reference 교체
    • initialization
      • static variable 에 value 할당 (value in code)
      • static initializer 실행 (static block)
  • Runtime data area
    • Method area : class data
      • Java8 이전에는 Method area 를 PermGen space 라고 지칭. -XX {MaxPermSize} 로 PermGen space 크기를 튜닝할 수 있었음. (Default : 64MB)
    • Heap area : object data
      • -Xms : Heap area 최소 크기 설정 옵션
      • -Xmx : Heap area 최대 크기 설정 옵션
    • Stack memory : function stacks, local variables, parameters …
      • thread 별로 독립적으로 갖는다.
      • -Xss : Stack memory 크기 설정 옵션
    • Pc register: pointing to current executing instruction
      • thread 별로 독립적으로 갖는다.
    • native method stack : native method(function) data
  • Execution Engine
    • Interpreter
    • JIT Compiler
    • Hotspot profiler
    • Garbage collector : clear unused objects, classes
    • Java Native method Interface(JNI)
      • jre/bin 에 있는 native method libraries 사용
      • Interpreter가 JNI를 이용해서 instruction을 실행시킴.

 


 

JDK와 JRE의 차이

  • JRE : Java Runtime Environment
    • compiled Java program을 실행하기 위해 필요한 package
    • e.g. JVM, Java class library, java command …
  • JDK : Java Development Kit
    • Java program 을 만들고 컴파일 하기 위한 package
    • JRE + javac(compiler) + javadoc, jdbc …


(참고) JRE 와 JDK 는 사실 directory 의 집합이다.

Mac 의 경우, /Library/Java/JavaVirtualMachines/{jdk}/Contents/Home 경로에 가면 여러 디렉토리가 들어 있는데, 이 디렉토리들이 곧 JRE 이다.
JDK 는 위 JRE 에 여러 파일 혹은 디렉토리가 추가되는 것이다. 가령, bin/ 에 jar, Java, javadoc, jshell 등이 더해진다.

https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre

 


 

References

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함