2025년 3월 27일부터 AOSP를 빌드하고 기여하려면 aosp-main
대신 android-latest-release
를 사용하는 것이 좋습니다. 자세한 내용은 AOSP 변경사항을 참고하세요.
ART JIT(Just-In-Time) 컴파일러 구현
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
Android 런타임(ART)에는 Android 애플리케이션 실행 시 성능을 지속적으로 개선하는 코드 프로파일링 기능이 있는 JIT 컴파일러가 포함되어 있습니다.
JIT 컴파일러는 ART의 현재 AOT(ahead-of-time) 컴파일러를 보완하고 런타임 성능을 개선하며 저장공간을 절약하고 애플리케이션 및 시스템 업데이트를 가속화합니다. 또한 무선 업데이트(OTA)가 진행되는 동안 자동 애플리케이션 업데이트나 애플리케이션 재컴파일로 인한 시스템 속도 저하를 방지하여 AOT 컴파일러를 개선합니다.
JIT와 AOT는 유사하게 최적화된 동일한 컴파일러를 사용하지만 생성된 코드는 동일하지 않을 수 있습니다. JIT는 런타임 유형 정보를 활용하며 인라이닝을 개선할 수 있고 스택상 교체(OSR) 컴파일을 가능하게 합니다. 이러한 모든 작업에 따라 조금씩 다른 코드가 생성됩니다.
JIT 아키텍처
그림 1. JIT 아키텍처입니다.
JIT 컴파일
JIT 컴파일에는 다음과 같은 작업이 포함됩니다.
그림 2. 프로필 기반 컴파일입니다.
- 사용자가 앱을 실행하면 ART가 트리거되어
.dex
파일을 로드합니다..oat
파일(.dex
파일의 AOT 바이너리)을 사용할 수 있는 경우 ART는 이를 직접 사용합니다. .oat
파일이 정기적으로 생성되더라도 컴파일된 코드(AOT 바이너리)가 항상 포함되지는 않습니다.
.oat
파일에 컴파일된 코드가 없으면 ART가 JIT와 인터프리터를 통해 실행되어 .dex
파일을 실행합니다.
- JIT는
speed
컴파일 필터에 따라 컴파일되지 않은 모든 애플리케이션에 사용 설정됩니다. 즉 '앱에서 가능한 만큼 컴파일'할 수 있습니다.
- JIT 프로필 데이터는 애플리케이션만 액세스할 수 있는 시스템 디렉터리의 파일로 덤프됩니다.
- AOT 컴파일(
dex2oat
) 데몬은 컴파일을 위해 파일을 파싱합니다.
그림 3. JIT 데몬 작업입니다.
Google Play 서비스는 공유 라이브러리와 유사한 방식으로 동작하는 다른 애플리케이션에서 사용되는 예입니다.
JIT 워크플로
그림 4. JIT 데이터 흐름입니다.
- 프로파일링 정보는 코드 캐시에 저장되며 메모리 부족 시 가비지 컬렉션이 실행됩니다.
- 애플리케이션이 백그라운드에 있었을 때 생성된 스냅샷에 완전한 데이터(JIT로 컴파일된 모든 데이터)가 포함된다는 보장은 없습니다.
- 런타임 성능에 영향을 줄 수 있으므로 모든 항목이 기록될 수 있도록 시도하지 않습니다.
- 메서드의 상태는 다음 3가지일 수 있습니다.
- 해석된 dex 코드
- JIT로 컴파일됨
- AOT로 컴파일됨
예를 들어 반복적인 역최적화로 인해 JIT와 AOT 코드가 모두 존재하는 경우 JIT로 컴파일된 코드를 사용하는 것이 좋습니다.
- 포그라운드 앱 성능에 영향을 주지 않고 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
특정 패키지를 강제 컴파일하는 일반적인 사용 사례:
모든 패키지를 강제 컴파일하는 일반적인 사용 사례:
프로필 데이터 삭제
프로필 데이터를 삭제하고 컴파일된 코드를 제거하려면 다음을 실행합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2024-05-07(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2024-05-07(UTC)"],[],[],null,["# Implement ART just-in-time compiler\n\nAndroid runtime (ART) includes a just-in-time (JIT) compiler with code profiling\nthat continually improves the performance of Android applications as they run.\nThe JIT compiler complements ART's current ahead-of-time (AOT) compiler and\nimproves runtime performance, saves storage space, and speeds application and\nsystem updates. It also improves upon the AOT compiler by avoiding system\nslowdown during automatic application updates or recompilation of applications\nduring over-the-air (OTA) updates.\n\n\nAlthough JIT and AOT use the same compiler with a similar set of optimizations,\nthe generated code might not be identical. JIT makes use of runtime type\ninformation, can do better inlining, and makes on stack replacement (OSR)\ncompilation possible, all of which generates slightly different code.\n\nJIT architecture\n----------------\n\n**Figure 1.** JIT architecture.\n\nJIT compilation\n---------------\n\nJIT compilation involves the following activities:\n**Figure 2.** Profile-guided compilation.\n\n1. The user runs the app, which then triggers ART to load the `.dex` file.\n - If the `.oat` file (the AOT binary for the `.dex` file) is available, ART uses it directly. Although `.oat` files are generated regularly, they don't always contain compiled code (AOT binary).\n - If the `.oat` file does not contain compiled code, ART runs through JIT and the interpreter to execute the `.dex` file.\n2. JIT is enabled for any application that is not compiled according to the `speed` compilation filter (which says \"compile as much as you can from the app\").\n3. The JIT profile data is dumped to a file in a system directory that only the application can access.\n4. The AOT compilation (`dex2oat`) daemon parses that file to drive its compilation. \n\n **Figure 3.** JIT daemon activities.\n\n\nThe Google Play service is an example used by other applications that behave\nsimilar to shared libraries.\n\nJIT workflow\n------------\n\n**Figure 4.** JIT data flow.\n\n- Profiling information is stored in the code cache and subjected to garbage collection under memory pressure.\n - There is no guarantee a snapshot taken when the application was in the background will contain complete data (i.e., everything that was JITed).\n - There is no attempt to ensure everything is recorded (as this can impact runtime performance).\n- Methods can be in three different states:\n - interpreted (dex code)\n - JIT compiled\n - AOT compiled\n If both JIT and AOT code exists (e.g. due to repeated de-optimizations), the JITed code is preferred.\n- The memory requirement to run JIT without impacting foreground app performance depends upon the app in question. Large apps require more memory than small apps. In general, large apps stabilize around 4 MB.\n\nTurn on JIT logging\n-------------------\n\nTo turn on JIT logging, run the following commands: \n\n adb root\n adb shell stop\n adb shell setprop dalvik.vm.extra-opts -verbose:jit\n adb shell start\n\nDisable JIT\n-----------\n\nTo disable JIT, run the following commands: \n\n adb root\n adb shell stop\n adb shell setprop dalvik.vm.usejit false\n adb shell start\n\nForce compilation\n-----------------\n\nTo force compilation, run the following: \n\n```\nadb shell cmd package compile\n```\n\nCommon use cases for force compiling a specific package:\n\n- Profile-based: \n\n ```\n adb shell cmd package compile -m speed-profile -f my-package\n ```\n- Full: \n\n ```\n adb shell cmd package compile -m speed -f my-package\n ```\n\nCommon use cases for force compiling all packages:\n\n- Profile-based: \n\n ```\n adb shell cmd package compile -m speed-profile -f -a\n ```\n- Full: \n\n ```\n adb shell cmd package compile -m speed -f -a\n ```\n\nClear profile data\n------------------\n\n### On Android 13 or earlier\n\nTo clear local profile data and remove compiled code, run the following: \n\n```\nadb shell pm compile --reset \n```\n\n### On Android 14 or later\n\nTo clear local profile data only: \n\n```\nadb shell pm art clear-app-profiles \n```\n\nNote: Unlike the command for Android 13\nor earlier, this command doesn't clear external profile data (\\`.dm\\`) that is\ninstalled with the app.\n\nTo clear local profile data and remove compiled code generated from local\nprofile data (i.e., to reset to the install state), run the following: \n\n```\nadb shell pm compile --reset \n```\n\nNote: This command doesn't remove compiled code generated from\nexternal profile data (\\`.dm\\`) that is installed with the app.\n\nTo clear all compiled code, run this command: \n\n```\nadb shell cmd package compile -m verify -f \n```\n\nNote: This command retains local profile data."]]