본문 바로가기
Programming Language 이해하기/Java 이해하기

#1 스터디 할래 - 1주차

by simplify-len 2021. 10. 30.

1. JVM이란 무엇인가?

JVM 은 Java Virtual Machine 의 약자로서, Java 가 동작될 때 동작될 수 있는 플랫폼을 제공해준다. 이는 즉 다시 말하면 Java로 개발한 프로그램을 컴파일하여 만들어지는 바이트코드를 실행시킬 수 있는 가상머신이다.

 

JVM 의 가장 큰 특징으로는 Write one, Run anywhere 라는 모토이다. 이는 어떤 OS의 제약에도 해당되지 않는 것과 같다.

JVM의 컴파일러가 .java 소스파일을 컴파일하면 .class 클래스 파일을 JVM에게 건네주게 되면 JVM이 클래스파일을 메모리에 로드하여 실행할 수 있다.

 

여기서 컴파일러는 프론트엔드에 속하고, JVM은 백엔드에 속한다. 이말은 위에서 말한것과같이 .java 를 Compiler 를 통해 Compile 하면 백엔드에 속하는 JVM에서 실행시킴을 의미합니다.

 

크게 3부분으로 나눠지는데, Class Loader System, Runtime Data Area, Execution Engine 으로 나눠진다.

JVM 아키텍쳐

Class Loader 는 RunTime 시점에 클래스를 로딩하게 해주며, 클래스의 인스턴스를 생성하면 클래스로더를 통해 메모리에 로드하게 됩니다.

Runtime Data Area JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당받은 메모리 공간을 말합니다.

Execution Engine 은 Load된 Class의 ByteCode 를 실행하는 Runtime Module 이 바로 Execution Engine.

 

2. 컴파일 하는 방법& 3.실행하는 방법

만약 IntelliJ 로 프로젝트를 열고 Hello World 를 Print 해주는 코드를 작성했다.

이를 어떻게 컴파일 할 수 있을까?

package com.example;

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

예상은 Javac Main.java 하고 나서, Java Main 을 하면 될 줄 알았지만 안된다. 왜냐하면, Package 가 지정되어 있는 자바파일은 package가 지정된 상위 폴더에서 실행 시켜야 한다.

 

잘못된 곳에서 실행시킬 경우 아래와 같은 에러가 발생한다.

잘못된 위치에서 실행 시킬 경우

 

잘되는 케이스

다시 돌아가서 컴파일하는 방법은 javac com/example/Main.java  이렇게 하면 된다.

 

만약 인코딩이 필요하다면?

↳ javac -encoding utf-8  com/example/Main.java 

 

그 외에도 여러 옵션이 있다. 해당 블로그를 참고하자!

4.바이트코드란 무엇인가.

Byte 코드는 위에서 언급한 Compiler에 의해서 .java 파일이 .class 로 변경되면 이때 .class 파일을 바이트코드라고 합니다.

이는 컴퓨터가 이해할 수 있는 언어로 변경되었음을 의미한다. 

위 Hello World 의 바이트 코드는 어떻게 볼수 있을까? IntelliJ 에서는 이런 기능을 제공해준다.

 

Show ByteCode

이를 통해 내용을 확인해보면 아래와 같다.

그림2 - ByteCode

알 수 없는 내용으로 가득하지만, 이는 컴퓨터가 이해할 수 있는 용어이기 때문이다.

When developers are first introduced to the JVM, they sometimes think of it as “a computer inside a computer.” It’s then easy to imagine bytecode as “machine code for the CPU of the internal computer” or “machine code for a made­up processor.” - Java in a Nutshell

 

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

 전통적인 입장에서 컴퓨터 프로그램을 만드는 방법은 두 가지가 있는데, 인터프리트 방식과 정적 컴파일 방식으로 나눌 수 있다. 이 중 인터프리트 방식은 실행 중 프로그래밍 언어를 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행하며, 반면 정적 컴파일은 실행하기 전에 프로그램 코드를 기계어로 번역한다.

JIT 컴파일러는 두 가지의 방식을 혼합한 방식으로 생각할 수 있는데, 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.
최근의 자바 가상 머신과 .NET, V8(node.js)에서는 JIT 컴파일을 지원한다. 즉, 자바 컴파일러가 자바 프로그램 코드를 바이트코드로 변환한 다음, 실제 바이트코드를 실행하는 시점에서 자바 가상 머신이 바이트코드를 JIT 컴파일을 통해 기계어로 변환한다.

 - 위키디피아

 

 앞서 Javac 를 통해 .java 파일을 컴파일 한다고 언급했습니다. 컴파일 한 결과물은 그림2와 같은 내용이 나오는데요. JIT 컴파일러는 이렇게 나온 바이트코드를 Runtime 즉 사용하는 시점에 원시 기계코드로 컴파일하여 Java 프로그램의 성능을 향상시켜 주는 것입니다.

그림 3 - JIT Compiler 동작 순서

JIT 컴파일러는 메서드의 바이트 코드를 원시 기계 코드로 컴파일하여 "적시에(JUST IN TIME)" 실행되도록 컴파일합니다. 메소드가 컴파일 되면 JVM은 해석하는 대신 해당 메소드의 컴파일된 코드를 직접 호출합니다. 만약 자주사용되는 함수라면 JIT 컴파일러에 의해 캐싱되는 효과도 있어 성능을 향상시킵니다.

6. JVM 구성 요소

JVM 의 구성요소는 위에서 언급한 것과 같이 크게 3가지로 나뉘집니다.

1. Class Loader

2. Runtime Data Area

3. Exection Engine(실행엔진)

그림 4 JVM 아키텍쳐

https://sas-study.tistory.com/262

 

7. JDK와 JRE의 차이

JRE는 컴파일된 자바 프로그램을 실행시킬 수 있는 자바 환경을 말합니다.

또한 JRE은 JVM의 실행 환경을 구현했다는 것과 같습니다. 그러므로 JRE 는 JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있습니다.

 

JDK는 자바 프로그래밍시 필요한 컴파일러를 포함합니다.

즉, 개발에 필요한 도구가 포함되며, JDK를 설치하게되면 JRE도 같이 설치된다고 생각할 수 있습니다.

 

참고

1. JIT 컴파일러 - https://ko.wikipedia.org/wiki/JIT_%EC%BB%B4%ED%8C%8C%EC%9D%BC  

2. https://developers.redhat.com/articles/2021/06/23/how-jit-compiler-boosts-java-performance-openjdk#deoptimization_and_speculation  

3. https://sas-study.tistory.com/262     
4. https://medium.com/@lazysoul/jvm-%EC%9D%B4%EB%9E%80-c142b01571f2  

댓글