카테고리 없음

JVM 공부한 내용 정리

우디혜 2021. 2. 17. 23:52

Java

제임스 고슬링 + 빌 조이

한 번 쓰고 모든 곳에서 실행하겠다라는 철학

인터넷 시대에 접어들면서 Java가 성공 가도를 달렸다. 왜? 자바 애플릿 때문!

자바 애플릿은 어떤 컴퓨터의 어떤 브라우저에서도 똑같은 코드를 실행할 수 있게 자바 바이트 코드 형태로 배포되는 애플릿을 말한다. (⁕ 애플릿 : Application + -let(작은) = 작은 어플리케이션)

자바를 컴파일한 코드를 클래스 파일이라고 한다. 그 클래스 파일 안에는 자바 바이트 코드가 들어있다. 그리고 이 자바 바이트 코드는 JVM이 실행할 수 있다.

 

JRE ( Java Runtime Environment )

자바 프로그램 실행에 필요한 요소들이 들어있다. JVM, 필수 라이브러리(rt.jar), JIT 컴파일러 등으로 구성되어 있다.

 

JDK ( Java Development Kit )

자바 개발을 위해 필요한 컴파일러(javac.exe), 인터프리터(java.exe), 디버거 등이 들어있다. JDK 안에 JRE도 포함되어있다.(JDK = JRE + 컴파일러, 인터프리터 등 개발 도구)

 

그래서 자바 개발을 하고 싶은 사람들은 JDK를, 자바 프로그램을 실행만 시키고 싶다면 JRE를 설치하면 된다.

 


 

JVM이란

자바 가상 머신(Java Virtual Machine) 자바 바이트 코드를 기계어로 해석해서 OS에 전달해주는 가상 머신이다. 바이트 코드로 바로 번역되려면 OS마다 바이트 코드가 달라지기 때문에 OS에 종속적일 수 밖에 없다. 하지만 JVM이 자바 프로그램과 OS의 중간 번역 역할을 해주기 때문에 자바 프로그램은 OS와 디바이스에 종속적이지 않다 (JVM 자체는 OS에 종속적이다, JRE나 JDK 설치 시 OS 버전 별로 인스톨러가 별개인 이유도 이 때문이다).

 

ClassLoader Subsystem

Loading

  • 필요할 때(동적으로) 클래스 정보(FQCN)를 통해 해당 클래스 파일을 찾고 바이트 코드로 읽어서 메모리에 로딩
  • Loading is the process of finding the binary representation of a class or interface type with a particular name(이게 FQCN를 말하는 것 같다) and creating a class or interface from that binary representation

⁕ 클래스를 동적으로 메모리에 로딩(== 클래스 파일을 런타임 데이터 영역에 적재)

  • '동적'으로 메모리에 로딩하는 이유
    • 클래스를 전부로딩하지 않고 필요한 시점(실제 실행이 되었을 시점)이 되었을 때가 되어서야 메모리에 로딩이 된다
    • c언어의 dynamic linking과 유사하다
    • 엇 자바에서도 dyanamic linking이라고 한다. - 참고

 

Linking

  • 클래스 파일 검사(자바 규칙을 따르는지 검증, 현재 클래스가 참조하는 다른 클래스 로딩), static 변수를 기본값(0)으로 저장

Initialization

  • static 변수를 초기값으로 저장, static block 실행하는 등 모든 정적 변수를 할당하는 과정

 

Runtime Data Area

Method area

  • 클래스 로더에서 읽어온 클래스 정보들을 파싱해서 저장

Heap

  • The heap is the run-time data area from which memory for all class instances and arrays is allocated (동적으로 생성되는 데이터들의 영역)
  • 프로그램 실행 후 생성된 객체 인스턴스 혹은 배열 저장

PC(Program Counter) 레지스터

  • 각 스레드에서 다음에 실행될 명령어 주소를 스레드 별로 저장(스레드 실행시 어디부터 실행해야하는지 가리키는 포인터 같은 존재)

Stack(call stack)

  • 각 스레드별로 하나씩 존재
  • 메서드 호출 시 스택 프레임이 하나씩 생성
  • local primitive values, reference value of the object

Native method stacks

  • 각 스레드별로 하나씩 존재
  • 자바 바이트 코드가 아닌 언어로 작성된 메서드를 위한 스택

☝ 쓰레드 마다 존재하는 PC(Program Counter), Stack, Native method stacks

Execution Engine

인터프리터

  • 바이트 코드를 한줄 한줄 해석 · 실행
  • 오래걸린다는 단점이 있다.

JIT 컴파일러 (Just In Time)

  • 인터프리터의 느린 점을 보완하기 위해서 JIT 컴파일러는 바이트 코드를 컴파일하고서 native machine code로 번역해놓는다. 그리고 동일한 바이트 코드 시퀀스에 대해서는 이미 번역이 된 native machine code를 사용해서 성능을 높여주는 역할을 한다.

Garbage Collector

  • automatic storage management system
  • 참조되지 않는 객체를 deallocate
  • (+) 리스프의 문제 해결을 위해서 존 매카시가 개발

알아두면 좋은 Java 상식

Java 파일 특징

  • 하나의 소스 파일(.java)에 둘 이상의 public class가 존재하면 안된다.
  • 클래스 파일(.class)은 클래스마다 하나씩 만들어진다.

☝ 디폴트 == 패키지 프라이빗

 

Java는 pass by value

  • primitive variable

    아래 코드에서 addOne()이 호출될 때는 number 변수가 가진 값 3이 복사되어 copiedNumber 변수에 저장된다.

int number = 3;
addOne(number); // 이때 number는 argument

void addOne(int copiedNumber){ // 이때 copiedNumber는 parameter
    System.out.println(copiedNumber + 1);
}

 

  • reference variable

    아래 코드에서도 greeting()이 호출될 때 word가 참조하고 있는 주소를 복사해오기 때문에 결국 참조'값'을 복사해온 것.
String word = new String("Hi");
greeting(word);

public void greeting(String copiedWord) {
    System.out.println(copiedWord);
}

 

FQCN (fully qualified class name)

  • 패키지명 + 클래스 이름
  • 클래스를 유니크하게 구분할 수 있다.

[10분 테코톡] 무민의 JVM Stack & Heap

Chapter 5. Loading, Linking, and lnitializing - ClassLoader에 대한 내용이지만 너무 어려워서 맨 앞부분만 참고

JVM의 구조 - ClassLoader 위주

Chapter 2 - The Structure of the Java Virtual Machine - Runtime Data Area 위주로 참고. 마찬가지로 어려워서 내가 읽고싶은 부분, 읽을 수 있는 부분만 읽었다.

Just In Time Compiler