JVM
🤔 java HelloWorld 라는 명령을 실행하면?
1. OS는 가상 머신 프로세스(java binary)를 구동한다.
2. 자바 가상 환경이 구성된다.
3. stack 머신이 초기화 된다.
4. HelloWorld 클래스가 실행된다.
여기서 application 의 진입은 HelloWorld.class 의 main() method 이다.
제어권을 이 클래스로 넘기기 위해 가상 머신(이하 VM) 이 실행되기 전에 이 클래스를 load 해야한다.
classloading 매커니즘
자바 process 가 초기화되면 사슬처럼 연결된 클래스 로더가 차례차례 작동한다.
1. bootstrap class 실행
다른 클래스로더가 나머지 시스템에 필요한 class 를 로드할 수 있게 최소한의 필수 클래스만 로드한다.
java.lang.Object, Class, Cloassload 가 이에 해당함
2. java ≤ 8 은 rt.jar 에서 runtime core class 를 로드한다.
java > 9 는 runtime 이 모듈화 되고 클래스 로딩 개념 자체가 달라졌다.
3. 확장 클래스 로더(The Extension classloader)
OS나 플랫폼에 native code 를 제공하고 기본 환경을 overriding 하는데 사용된다.
bootstrap 을 부모로 인식하여 필요할 때 부모로 클래스 로딩 작업을 넘긴다.
4. 끝으로 application class loader 가 생성된다.
classpath 에 위치한 user class 를 로드한다.
종종 이 클래스 로더를 system class load 라고 부르기도 하는데 이는 system 에 관련된 클래스를 로드하지 않기 때문에 사용하지 않는 것을 권장한다.
👩🏻💻 이는 모두 상속 관계이다. bootstrap (최상단 부모) → extension classload → application classloader (최하단 자식)
java program 을 실행하다가 새 클래스를 발견하여 찾지 못하면 한 단계씩 상위로 올려 lookup 을 하고, 만약 찾지 못한다면 ClassNotFoundException 을 일으킨다. java 의 클래스를 로드하는 것은 runtime 에서 해당 클래스를 나타내는 Class 객체를 만들어 내는데 이것은 runtime 에서 결정되기 때문에 상이한 클래스를 두번 load 할 수 있어 주의가 필요하다.
* 클래스의 식별: 패키지명을 포함하여 full class 이름 + 자신을 로드한 classloader 두가지 정보로 식별한다.
바이트코드 실행 (Executing Bytecode)
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println(3+4);
}
}
이 코드를 javac HelloWorld.java 로 실행하면 다음과 같이 HelloWorld.class 로 compile 된 파일이 생성된다.
˛∫æ7
<init>()VCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFileHelloWorld.java Hello World!
HelloWorldjava/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(Ljava/lang/String;)V(I)V
*∑±
1≤∂≤∂±
컴파일하여 생성된 bytecode HelloWorld.class
이렇게 생성된 bytecode 는 별도의 최적화 작업이 수행되지 않기 때문에 해독이 쉽다(컴퓨터 입장에서)
Bytecode
bytecode 는 컴퓨터의 아키텍쳐에 특정되지 않는 중간 표현형(Intermediate Representation, IR) 이다. 따라서 이식성이 좋고, JVM 이 지원되는 플랫폼 어디서든 실행할 수 있으며, java 에 대해서 추상화 되어있다. JVM이 코드를 실행하는 원리를 이해하는데 중요하다.
컴파일러가 생성한 .class 파일은 VM spec 에 명확히 정의된 구조를 갖추고 있다.
JVM 메모리 관리 (JVM Memory Management)
C, C++ 은 메모리를 개발자가 직접 관리하는데, 이 책임이 개발자에게 오면 막중환 책임이 수반된다. 자바는 Garbage Collection(이하 GC) 라는 프로세를 이용해 heap memory 를 자동으로 관리한다. GC는 JVM이 더 많은 메모리를 할당해야 할 때 불필요한 메모리를 회수하거나 재사용하는 불확정적 프로세스이다. GC가 실행되면 그 동안 다른 애플리케이션은 모두 중단되고 하던일을 멈춰야 하는데 이것은 애플리케이션의 부하가 늘어날 수록 무시할 수 없는 시간이 된다.
참고 : https://d2.naver.com/helloworld/37111
https://blog.yevgnenll.me/posts/optimizing-java-jvm-overview