[1주차] 자바 소스 파일을 JVM으로 실행하는 과정 이해하기

River Kim·2021년 5월 23일
0

Java Study

목록 보기
1/2
post-thumbnail

목표

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

학습할 것

  • JVM이란 무엇인가
  • 컴파일 하는 방법
  • 실행하는 방법
  • 바이트코드란 무엇인가
  • JIT 컴파일러란 무엇이며 어떻게 동작하는가
  • JVM 구성 요소
  • JDK와 JRE의 차이

추가 과제

  • javac 옵션 조사


JVM이란 무엇인가

  • Java Virtual Machine
  • Java 바이트코드를 OS에 특화된 코드로 변환(인터프리터와 JIT 컴파일러)하여 실행

JVM 구성 요소

  • 클래스 로더
  • 메모리(Runtime Data Area)
  • 실행 엔진

JDK와 JRE의 차이

  • JRE(Java Runtime Environment): 자바 API + JVM
    • Java Application 실행 목적
    • Java11 부터는 제공되지 않음
  • JDK(Java Development Kit): JRE + 개발 툴

컴파일하는 방법

  • javac: 자바 컴파일러
    • .java 파일을 .class 파일로 컴파일
  • .java 파일 생성 후 javac <FileName>.java 커맨드 실행

HelloWorld 파일 생성 및 HelloJava 클래스 작성

$ vi HelloWorld.java  # .java 생성
class HelloJava
{
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

컴파일

$ ll
-rw-r--r--  1 max  staff  107  5 11 23:52 [1]  HelloWorld.java

# javac 커맨드로 컴파일
$ javac HelloWorld.java

$ ll
# HelloWorld.java 파일 내에 작성한 HelloJava 클래스가 파일로 생성: 바이트코드
-rw-r--r--  1 max  staff  425  5 11 23:53 [1]  HelloJava.class
-rw-r--r--  1 max  staff  107  5 11 23:52 [2]  HelloWorld.java

실행하는 방법

  • java <ClassName> 커맨드 사용
$ java HelloJava
Hello World!  # 실행 결과

자바 바이트코드란 무엇인가

  • JVM이 실행하는 명령어의 집합
  • 1바이트로 구성
    • 256개가 모두 쓰이진 않음
  • Java compiler: .java 파일 > .class(Java 바이트코드)
  • 바이트코드는 JVM 위에서 OS와 상관 없이 실행

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

  • 인터프리터
    • 바이트코드를 한줄씩 네이티브코드로 변환 및 실행
    • 한줄씩 실행하기 때문에 컴파일러에 비해 속도가 느림
  • JIT 컴파일러
    • 인터프리터 방식의 단점을 보완하기 위해 도입
    • 반복 사용되는 코드를 JIT 컴파일러가 네이티브코드로 컴파일 후 캐싱
      • 메소드 영역에 있는 코드 캐시(Code Cache) 공간에 캐싱
    • 인터프리팅 시 캐싱된 코드가 있으면 바로 사용
    • 반복 수행하지 않으면 인터프리터 방식이 빠름

javac 옵션

  • -classpath(-cp, --class-path): 의존성 라이브러리나 클래스 파일 경로 지정
  • -sourcepath(--source-path): 의존성 자바 파일 경로 지정

    부가 설명
    .java 파일을 컴파일하기 위해서는 자바 파일의 의존성을 해결해야 함
    classpath 옵션은 .class 파일 경로를,
    sourcepath 옵션은 .java 파일 경로를 지정

  • -d: 컴파일된 클래스 파일 저장 위치 지정
  • -encoding: 컴파일할 자바 파일의 인코딩 지정
  • -nowarn: 경고 보이지 않음
  • -g: 모든 디버깅 정보 생성
  • -g:{lines,vars,source}: 일부 디버깅 정보만 생성
  • -g:none: 디버깅 정보 생성하지 않음
$ ll
-rw-r--r--  1 max  staff  107  5 11 23:52 [1]  HelloWorld.java
drwxr-xr-x  3 max  staff   96  5 24 01:36 [2]  hello
drwxr-xr-x  3 max  staff   96  5 24 01:35 [3]  main


$ tree .
.
├── HelloWorld.java
├── hello
│   └── Hello.java
└── main
    └── App.java

2 directories, 3 files


# Hello 클래스를 찾을 수 없어 에러 발생
$ javac -d . main/App.java
main/App.java:3: error: cannot find symbol
        Hello.hello();
        ^
  symbol:   variable Hello
  location: class App
1 error


# sourcepath 옵션 사용하여 컴파일
$ javac -d . -sourcepath ./hello main/App.java


$ ll
-rw-r--r--  1 max  staff  287  5 24 01:52 [1]  App.class
-rw-r--r--  1 max  staff  392  5 24 01:52 [2]  Hello.class
-rw-r--r--  1 max  staff  107  5 11 23:52 [3]  HelloWorld.java
drwxr-xr-x  3 max  staff   96  5 24 01:36 [4]  hello
drwxr-xr-x  3 max  staff   96  5 24 01:35 [5]  main

$ java App
Hello World!

# App.class 파일 삭제
$ rm -rf App.class

$ ll
-rw-r--r--  1 max  staff  392  5 24 01:52 [1]  Hello.class
-rw-r--r--  1 max  staff  107  5 11 23:52 [2]  HelloWorld.java
drwxr-xr-x  3 max  staff   96  5 24 01:36 [3]  hello
drwxr-xr-x  3 max  staff   96  5 24 01:35 [4]  main


# classpath 옵션 사용하여 컴파일
$ javac -d . -classpath . main/App.java

$ ll
-rw-r--r--  1 max  staff  287  5 24 01:54 [1]  App.class
-rw-r--r--  1 max  staff  392  5 24 01:52 [2]  Hello.class
-rw-r--r--  1 max  staff  107  5 11 23:52 [3]  HelloWorld.java
drwxr-xr-x  3 max  staff   96  5 24 01:36 [4]  hello
drwxr-xr-x  3 max  staff   96  5 24 01:35 [5]  main

$ java App
Hello World!
profile
언제까지 개발자로 살 수 있을까..

0개의 댓글