[F-Lab 챌린지 50일차 TIL]

성수데브리·2023년 8월 16일
0

f-lab_java

목록 보기
40/73

Warming up 필요한 이유

1. 클래스 로더 lazy-loading

클래스 로더가 JVM 으로 .class 파일을 로딩할 때 lazy-loading 을 한다.
프로세스가 동작중에 필요한 클래스가 있으면 그때 그때 로딩을 한다.

그러므로 최초 자바 프로세스가 떴을때 최초 호출되는 클래스는 로딩 시간이 필요하다.

2. JIT 컴파일

JVM 은 프로그램 목적 파일을 기계언어가 아닌 중간 언어인 바이트 코드로 컴파일한다.
이 바이트코드는 JVM 내의 인터프리터에 의해 그때 그때 기계어로 변환되고 실행된다.
(모든 코드는 초기에 인터프리터에 의해서 시작된다)

컴파일러 언어의 장점은 한 번에 기계어로 변환 하면서 코드 최적화를 수행할 수 있는데,
인터프리터 언어는 그게 불가능하다. 그래서 자바는 인터프리터 + 컴파일러 방식을 혼합해서 사용한다.

JIT 컴파일러는 동적으로 자주 실행되는 코드를 분석해 메서드 단위로 미리 컴파일하여 코드 캐시라는 곳에 캐싱해둔다.

그러므로 JIT 컴파일 시간이 추가로 소요되긴 한다.

HotSpotVM 주요 컴포넌트

  1. VM 런타임
  2. JIT 컴파일러
  3. 메모리 관리자

JIT 컴파일러 최적화 방법

  • 각 메서드에 있는 카운터를 참조한다. 메서드에는 두 개의 카운터가 존재한다.
    1. 수행 카운터(Invocation counter) : 메서드를 시작할 때마다 증가

    2. 백에지 카운터(backedge counter) : 높은 바이트 코드 인덱스에서 낮은 인덱스로 컨트롤 흐름이 변경될 때마다 증가

      한계치공식:CompileThresholdOnStackReplacePercentage/100한계치 공식 : CompileThreshold * OnStackReplacePercentage / 100
  • 이 카운터들이 인터프리터에 의해서 증가될 때마다, 그 값들이 한계치에 도달했는지 확인하고, 도달했을 경우 인터프리터는 컴파일을 요청한다.

JTI 컴파일러 동작 순서

  1. 인터프리터 컴파일 요청 → 큐 적재 → 컴파일러 스레드 모니터링 시작
  2. 요청이 완료되지 않으면 인터프리터는 수행 카운터를 리셋하고 인터프리터에서 메서드 수행을 계속한다.
  3. 컴파일이 종료되면, 컴파일된 코드와 메서드가 연결. 이후부터는 코드 캐시의 코드가 실행된다.

JVM 시작 절차 (Java.exe 프로세스)

  1. java 명령어
  2. heap 크기 할당, JIT 컴파일러 타입 지정
  3. 환경변수 지정
  4. 지정한 Main 클래스 확인. 없으면 Jar 파일의 manifest 파일에서 확인
  5. JNI_CreateJavaVM 으로 non-primordial 스레드에서 HotSpotVM 생성
  6. Main 클래스의 main 메서드 속성 정보 읽기
  7. JVM 의 CallStaticVoidMethod 의해 메인 메서드가 실행된다.

클래스 로딩 절차

loading → linking → initializing

중간 언어로 컴파일하는 이유

  • 바이트 코드를 실행시에 기계어로 변환하게 함으로써 자바 플랫폼에 종속적이게 만들 수 있다.
  • 이식성이 생김

GC

  • full GC 를 수행하는 시점에는 해당 JVM 에서 처리되지 않기때문에 GC 가 자주 수행되면 응답 시간에 많은 영향을 끼친다.
  • JVM 은 메모리를 GC 라는 알고리즘으로 관리한다. 더이상 참조되지 않는 고아객체를 메모리에서 제거해주는 작업이다.

JVM 의 runtime data area

  1. PC 레지스터
  2. JVM 스택
  3. heap ———→ GC 가 발생하는 영역
  4. 메서드 영역
  5. 런타임 상수 풀
  6. 네이티브 메서드 스택

GC

  • 의존관계 최적화
  • 메모리 파편화 방지
  • GC Roots
    • Stack 데이터
    • 메서드 static 데이터
    • JNI 로 만들어진 데이터
  • GC 방식 5가지
  • CG 알고리즘의 트레이트 오프는 주로 할당 및 수명과 연관되어있음
  • JVM 은 에덴을 여러 버퍼로 나누어 각 스레드가 새 객체를 할당하는 구역으로 활용하도록 배포한다.

0개의 댓글