ART JIT(Just-In-Time) 컴파일러 구현

Android 런타임(ART)에는 실행되는 Android 애플리케이션의 성능을 지속적으로 개선하는 코드 프로파일링이 포함된 JIT(Just-In-Time) 컴파일러가 포함되어 있습니다. JIT 컴파일러는 ART의 현재 AOT(Ahead-of-Time) 컴파일러를 보완하고 런타임 성능을 개선하고 저장 공간을 절약하며 애플리케이션 및 시스템 업데이트 속도를 높입니다. 또한 자동 애플리케이션 업데이트 중 시스템 속도 저하를 방지하거나 무선(OTA) 업데이트 중 애플리케이션 재컴파일을 방지하여 AOT 컴파일러를 개선합니다.

JIT 및 AOT는 유사한 최적화 세트로 동일한 컴파일러를 사용하지만 생성된 코드는 동일하지 않을 수 있습니다. JIT는 런타임 유형 정보를 사용하고 더 나은 인라인을 수행할 수 있으며 스택 교체(OSR) 컴파일을 가능하게 하며 이 모든 것이 약간 다른 코드를 생성합니다.

JIT 아키텍처

JIT 아키텍처
그림 1. JIT 아키텍처.

JIT 컴파일

JIT 컴파일에는 다음 활동이 포함됩니다.

프로필 기반 광고
그림 2. 프로필 기반 컴파일.
  1. 사용자가 앱을 실행하면 ART가 .dex 파일을 로드하도록 트리거합니다.
    • .oat 파일( .dex 파일의 AOT 바이너리)을 사용할 수 있는 경우 ART는 이를 직접 사용합니다. .oat 파일은 정기적으로 생성되지만 항상 컴파일된 코드(AOT 바이너리)를 포함하지는 않습니다.
    • .oat 파일에 컴파일된 코드가 포함되어 있지 않으면 ART는 JIT 및 인터프리터를 통해 실행되어 .dex 파일을 실행합니다.
  2. JIT는 speed 컴파일 필터("앱에서 가능한 한 많이 컴파일")에 따라 컴파일되지 않은 모든 응용 프로그램에 대해 활성화됩니다.
  3. JIT 프로필 데이터는 응용 프로그램만 액세스할 수 있는 시스템 디렉터리의 파일에 덤프됩니다.
  4. AOT 컴파일( dex2oat ) 데몬은 해당 파일을 구문 분석하여 컴파일을 구동합니다.

    JIT 데몬
    그림 3. JIT 데몬 활동.

Google Play 서비스는 공유 라이브러리와 유사하게 동작하는 다른 애플리케이션에서 사용하는 예입니다.

JIT 워크플로

JIT 아키텍처
그림 4. JIT 데이터 흐름.
  • 프로파일링 정보는 코드 캐시에 저장되고 메모리 부족 상태에서 가비지 수집을 받습니다.
    • 애플리케이션이 백그라운드에 있을 때 찍은 스냅샷에 완전한 데이터(즉, JIT된 모든 것)가 포함된다는 보장은 없습니다.
    • 모든 것이 기록되도록 하려는 시도는 없습니다(이는 런타임 성능에 영향을 미칠 수 있으므로).
  • 메서드는 세 가지 다른 상태일 수 있습니다.
    • 해석(dex 코드)
    • JIT 컴파일
    • AOT 컴파일
    JIT 코드와 AOT 코드가 모두 존재하는 경우(예: 반복적인 최적화 해제로 인해) JITed 코드가 선호됩니다.
  • 포그라운드 앱 성능에 영향을 주지 않고 JIT를 실행하기 위한 메모리 요구 사항은 해당 앱에 따라 다릅니다. 큰 앱은 작은 앱보다 더 많은 메모리가 필요합니다. 일반적으로 큰 앱은 약 4MB에서 안정화됩니다.

JIT 로깅 켜기

JIT 로깅을 켜려면 다음 명령을 실행하십시오.

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

JIT 비활성화

JIT를 비활성화하려면 다음 명령을 실행합니다.

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

강제 컴파일

강제로 컴파일하려면 다음을 실행하십시오.

adb shell cmd package compile

특정 패키지를 강제 컴파일하는 일반적인 사용 사례:

  • 프로필 기반:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • 전체:
    adb shell cmd package compile -m speed -f my-package
    

모든 패키지를 강제 컴파일하는 일반적인 사용 사례:

  • 프로필 기반:
    adb shell cmd package compile -m speed-profile -f -a
    
  • 전체:
    adb shell cmd package compile -m speed -f -a
    

프로필 데이터 지우기

프로필 데이터를 지우고 컴파일된 코드를 제거하려면 다음을 실행하세요.

  • 한 패키지의 경우:
    adb shell cmd package compile --reset my-package
    
  • 모든 패키지의 경우:
    adb shell cmd package compile --reset -a