設定 ART

本頁面將說明如何設定 Android 執行階段 (ART) 及其編譯選項。本節討論的主題包括系統映像檔預先編譯的設定、dex2oat 編譯選項,以及如何權衡系統分區空間、資料分區空間和效能。

請參閱「ART 和 Dalvik」和「Dalvik 可執行檔格式」,瞭解如何與 ART 搭配使用。請參閱「在 Android 執行階段 (ART) 驗證應用程式行為」,確保應用程式正常運作。

ART 的運作方式

ART 會使用預先 (AOT) 編譯,並從 Android 7 開始,使用 AOT 編譯、即時 (JIT) 編譯和解譯的混合組合,且 AOT 編譯可由設定檔引導。所有執行模式的組合皆可設定,並會在本節中討論。舉例來說,Pixel 裝置會設為在以下流程中運作:

  1. 應用程式一開始安裝時,會使用 Play 商店發布的 dex 中繼資料 (.dm) 檔案,其中包含雲端設定檔。ART 會 AOT 編譯雲端設定檔中列出的方法。或者,如果安裝應用程式時沒有 DEX 中繼資料檔案,系統就不會執行 AOT 編譯。
  2. 應用程式執行的前幾次,會解譯未經 AOT 編譯的方法。在解譯方法中,經常執行的會以 JIT 編譯。ART 會根據執行作業產生本機設定檔,並與雲端設定檔 (如有) 結合。
  3. 當裝置處於閒置狀態並充電時,編譯守護程序會根據前幾次執行作業產生的合併設定檔,重新編譯應用程式。
  4. 在後續執行應用程式時,ART 會使用編譯守護程式產生的成果,其中包含比在未預先編譯的方法產生時,所產生更多 AOT 編譯程式碼。未預先編譯的方法仍會解讀或 JIT 編譯。ART 會根據執行作業更新設定檔安裝作業,然後在後續執行編譯守護程式時,系統會選取該設定檔。

ART 包含編譯器 (dex2oat 工具) 和在啟動期間載入的執行階段 (libart.so)。dex2oat 工具會取用 APK 檔案,並產生一或多個執行階段載入的編譯成果檔案。檔案數量、副檔名和名稱會因不同版本而異,但自 Android 8 版本起,系統會產生以下檔案:

  • .vdex:包含一些額外中繼資料,可加快驗證速度,有時會與 APK 的未壓縮 DEX 程式碼一併提供。
  • .odex:包含 APK 中方法的 AOT 編譯程式碼。
  • .art (optional) 包含 ART 內部對 APK 中列出的一些字串和類別的表示法,用於加快應用程式啟動速度。

編譯選項

ART 的編譯選項分為兩類:

  1. 系統 ROM 設定:建構系統映像檔時,AOT 編譯的程式碼為何。
  2. 執行階段設定:ART 如何在裝置上編譯及執行應用程式。

編譯器篩選器

編譯器篩選器是用來設定這兩個類別的一個核心 ART 選項。編譯器篩選器會決定 ART 編譯 DEX 程式碼的方式,並將選項傳遞至 dex2oat 工具。自 Android 8 起,官方支援四種篩選器:

  • verify:僅執行 DEX 程式碼驗證 (不進行 AOT 編譯)。
  • quicken:(Android 11 以下版本) 執行 DEX 程式碼驗證,並最佳化部分 DEX 指令,以提升轉譯器效能。
  • speed:執行 DEX 程式碼驗證,並以 AOT 方式編譯所有方法。不會為任何類別最佳化類別載入作業。
  • speed-profile:執行 DEX 程式碼驗證、AOT 編譯設定檔中列出的方法,並針對設定檔中的類別最佳化類別載入作業。

系統 ROM 設定

系統映像檔建構時,預先安裝的程式庫和應用程式會以 AOT 編譯。這項程序稱為 dexpreopt。只要所有依附元件都保持不變,尤其是啟動 classpath,這類編譯檔案就會可用。

注意:如果裝置採用系統模組更新,則開機路徑集很可能會在下次更新時變更,導致所有 dexpreopt 檔案失效,無法使用。

您可以使用多種 ART 建構選項來設定 dexpreopt。您如何設定這些選項,取決於系統映像檔的可用儲存空間,以及預先安裝應用程式的數量。編譯至系統 ROM 的 JAR/APK 可分為四類:

  • 啟動作業系統路徑集程式碼:預設使用 speed-profile 編譯器篩選器編譯。
  • 系統伺服器程式碼 (請參閱本文後面的 PRODUCT_SYSTEM_SERVER_JARSPRODUCT_APEX_SYSTEM_SERVER_JARSPRODUCT_STANDALONE_SYSTEM_SERVER_JARSPRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS):
    • (Android 14 以上版本) 預設使用 speed-profile 編譯器篩選器編譯,如果未提供設定檔,則會使用 speed 編譯器篩選器編譯。
    • (Android 13 以下版本) 預設使用 speed 編譯器篩選器編譯。
    可透過 PRODUCT_SYSTEM_SERVER_COMPILER_FILTER 進行設定 (請參閱本文件後續內容)。
  • 產品專屬核心應用程式 (請參閱本文件後續的 PRODUCT_DEXPREOPT_SPEED_APPS):根據預設,使用 speed 編譯器篩選器編譯。
  • 所有其他應用程式:預設使用 speed-profile 編譯器篩選器編譯,如果未提供設定檔,則使用 verify 編譯器篩選器編譯。

    可透過 PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER 進行設定 (請參閱本文後續內容)。

Makefile 選項

  • WITH_DEXPREOPT
  • 系統映像檔中安裝的 DEX 程式碼是否會叫用 dex2oat。預設為啟用。

  • DONT_DEXPREOPT_PREBUILTS (Android 5 以上版本)
  • 啟用 DONT_DEXPREOPT_PREBUILTS 可避免預先建構項目遭到 dexpreopt。這些應用程式在 Android.mk 中指定了 include $(BUILD_PREBUILT)。跳過對可能透過 Google Play 更新的預先建構應用程式進行 dexpreopt,可節省系統映像檔中的空間,但會增加首次開機時間。請注意,這個選項不會對 Android.bp 中定義的預先建構應用程式產生任何影響。

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (Android 9 以上版本)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER 可指定 dexpreopt 應用程式的預設編譯器篩選器。這些應用程式是在 Android.bp 中定義,或是在 Android.mk 中指定 include $(BUILD_PREBUILT)。如未指定,預設值為 speed-profile;如果未指定值且未提供設定檔,則預設值為 verify

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (自 Android 8 MR1 起)
  • 啟用 WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY 僅會將引導程序的類別路徑和系統伺服器 jar 檔案設為 dexpreopt。

  • LOCAL_DEX_PREOPT
  • 您也可以在模組定義中指定 LOCAL_DEX_PREOPT 選項,針對個別應用程式啟用或停用 Dexpreopt。這項功能可用於停用應用程式的 dexpreopt,因為應用程式可能會立即收到 Google Play 更新,而更新會使系統映像檔中的 dexpreopt 程式碼失效。這對於在 OTA 中進行主要版本升級時節省空間也非常實用,因為使用者可能已在資料分區中擁有較新版本的應用程式。

    LOCAL_DEX_PREOPT 支援 truefalse 值,分別用於啟用或停用 dexpreopt。此外,如果 dexpreopt 不應從 APK 或 JAR 檔案中移除 classes.dex 檔案,您可以指定 nostripping。一般來說,這個檔案會在 dexpreopt 之後遭到移除,因為屆時這個檔案已無用武之地,但這個最後的選項是必要的,才能讓第三方 APK 簽名保持有效。

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • 將選項傳遞至 dex2oat,以控制編譯作業系統映像檔的方式。可用來指定自訂圖片類別清單、編譯類別清單和編譯器篩選器。

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • 將選項傳遞至 dex2oat,以控制除了啟動映像檔以外的所有內容的編譯方式。

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • 可為特定模組和產品設定傳遞 dex2oat 選項。$(call add-product-dex-preopt-module-config,<modules>,<option>) 會在產品的 device.mk 檔案中設定此值,其中 <modules> 分別是 JAR 和 APK 檔案的 LOCAL_MODULELOCAL_PACKAGE 名稱清單。

  • PRODUCT_DEXPREOPT_SPEED_APPS (Android 8 以上版本)
  • 列出已識別為產品核心的應用程式,並建議使用 speed 編譯器篩選器進行編譯。舉例來說,SystemUI 等持續性應用程式只有在下次重新啟動時,才有機會使用設定檔導向編譯功能,因此產品最好讓這些應用程式一律以 AOT 編譯。

  • PRODUCT_SYSTEM_SERVER_APPS (Android 8 以上版本)
  • 系統伺服器載入的應用程式清單。這些應用程式預設會使用 speed 編譯器篩選器編譯。

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD (自 Android 8 起)
  • 是否要在裝置上加入 ART 偵錯版本。根據預設,這項功能會針對 userdebug 和 eng 版本啟用。如要覆寫這項行為,請明確將選項設為 truefalse

    根據預設,裝置會使用非偵錯版本 (libart.so)。如要切換,請將系統屬性 persist.sys.dalvik.vm.lib.2 設為 libartd.so

  • WITH_DEXPREOPT_PIC (Android 7 之前)
  • 在 Android 5.1.0 至 Android 6.0.1 中,您可以指定 WITH_DEXPREOPT_PIC 來啟用位置無關程式碼 (PIC)。這樣一來,您就不需要將映像檔中的編譯程式碼從 /system 重新定位至 /data/dalvik-cache,進而節省資料分割區的空間。不過,這會對執行階段造成輕微影響,因為它會停用可利用位置依附程式碼的最佳化功能。一般來說,如果裝置想在 /data 中節省空間,應啟用 PIC 編譯。

    在 Android 7.0 中,PIC 編譯功能預設為啟用。

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (Android 7 MR1 之前)
  • 這個選項已由 WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY 取代,後者也會預先選取系統伺服器 JAR。

  • PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
  • 這個選項會指定系統伺服器的編譯器篩選器。

    • (Android 14 以上版本) 如果未指定,系統會使用 speed-profile 編譯器篩選器,如果未提供設定檔,則會使用 speed 編譯器篩選器。
    • (Android 13 以下版本) 如果未指定,系統會使用 speed 編譯器篩選器。
    • 如果設為 speed,系統會使用 speed 編譯器篩選器。
    • 如果設為 speed-profile,系統會使用 speed-profile 編譯器篩選器,如果未提供設定檔,則會使用 verify 編譯器篩選器。
    • 如果設為 verify,系統會使用 verify 編譯器篩選器。

  • PRODUCT_SYSTEM_SERVER_JARSPRODUCT_APEX_SYSTEM_SERVER_JARSPRODUCT_STANDALONE_SYSTEM_SERVER_JARSPRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS
  • 以下是系統伺服器載入的 JAR 清單。使用 PRODUCT_SYSTEM_SERVER_COMPILER_FILTER 指定的編譯器篩選器編譯 JAR

    • (必要) PRODUCT_SYSTEM_SERVER_JARS:平台上的系統伺服器類別路徑 JAR 清單 (即 SYSTEMSERVERCLASSPATH 的一部分)。請務必將系統伺服器類別路徑 JAR 新增至此清單。如果未將系統伺服器類別路徑 JAR 新增至清單,就會導致這些 JAR 無法載入。
    • (必要) PRODUCT_APEX_SYSTEM_SERVER_JARS:系統伺服器 classpath JAR 清單,由 APEX 提供 (也就是 SYSTEMSERVERCLASSPATH 的一部分)。格式為 <apex name>:<jar name>。您必須將 APEX 系統伺服器類別路徑 JAR 新增至這份清單。如果未將 APEX 系統伺服器類別路徑 JAR 新增至這份清單,系統就不會載入這些 JAR。
    • (選用,Android 13 以下版本) PRODUCT_STANDALONE_SYSTEM_SERVER_JARS:系統伺服器使用個別類別載入器 (透過 SystemServiceManager.startServiceFromJar) 動態載入的 JAR 清單。雖然不一定要將獨立的系統伺服器 JAR 新增至此清單,但強烈建議這麼做,因為這樣一來 JAR 就會編譯,因此可獲得良好的執行階段效能。
    • (自 Android 13 起為必填) PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS:APEX 提供的 JAR 清單,系統伺服器會使用個別的類別載入器 (即透過 SystemServiceManager.startServiceFromJar 或宣告為 <apex-system-service>) 動態載入這些 JAR。格式為 <apex name>:<jar name>。您必須將獨立的 APEX 系統伺服器 JAR 新增至這份清單。如果未將獨立的 APEX 系統伺服器 JAR 新增至這份清單,就會導致啟動失敗。

    啟動類別路徑設定

    預先載入的類別清單是 Zygote 在啟動時初始化的類別清單。這樣一來,每個應用程式就不必分別執行這些類別初始化器,讓應用程式能更快啟動,並在記憶體中共用頁面。預先載入的類別清單檔案預設位於 frameworks/base/config/preloaded-classes,其中包含針對一般手機使用情況調整的清單。這項設定可能與穿戴式裝置等其他裝置不同,因此必須進行調整。調整時請小心,因為新增太多類別會在載入未使用的類別時浪費記憶體。新增的類別太少會迫使每個應用程式都必須擁有自己的副本,這又會浪費記憶體。

    使用範例 (在產品的 device.mk 中):

    PRODUCT_COPY_FILES += <filename>:system/etc/preloaded-classes
    

    注意:您必須將這行放在繼承任何產品設定檔案之前,才能從 build/target/product/base.mk 取得預設檔案。

    執行階段設定

    JIT 選項

    下列選項只會影響 ART JIT 編譯器可用的 Android 版本。

    • dalvik.vm.usejit:是否啟用 JIT。
    • dalvik.vm.jitinitialsize (預設為 64K):程式碼快取的初始容量。程式碼快取會定期執行 GC,並視需要增加。
    • dalvik.vm.jitmaxsize (預設為 64M):程式碼快取的最大容量。
    • dalvik.vm.jitthreshold (預設值為 10000):方法的「熱度」計數器必須達到這個門檻,才能透過 JIT 編譯方法。「熱度」計數器是執行階段的內部指標。包括呼叫次數、回溯分支和其他因素。
    • dalvik.vm.usejitprofiles (至 Android 13 為止):是否啟用 JIT 設定檔;即使 dalvik.vm.usejit 為 false,也可能會使用此設定。請注意,如果為 false,編譯器篩選器 speed-profile 就不會對任何方法進行 AOT 編譯,且等同於 verify。自 Android 14 起,JIT 設定檔一律會啟用,且無法關閉。
    • dalvik.vm.jitprithreadweight (預設為 dalvik.vm.jitthreshold / 20):應用程式 UI 執行緒的 JIT「取樣」(請參閱 jitthreshold) 權重。用於加快編譯方法的速度,這些方法會直接影響使用者與應用程式互動時的體驗。
    • dalvik.vm.jittransitionweight (預設為 dalvik.vm.jitthreshold / 10):在編譯程式碼和轉譯器之間轉換時,方法叫用的權重。這有助於確保相關方法已編譯,以盡量減少轉換 (轉換成本高昂)。

    Dex2oat 選項

    這些選項會影響裝置端編譯作業 (又稱為 dexopt),其中部分選項也會影響 dexpreopt,而上述「系統 ROM 設定」一節中討論的選項只會影響 dexpreopt。

    控管資源用量的選項:

    • dalvik.vm.image-dex2oat-threads/dalvik.vm.image-dex2oat-cpu-set (至 Android 11 為止):用於啟動映像檔的執行緒數量和 CPU 核心集合 (請參閱下方說明)。
    • dalvik.vm.boot-dex2oat-threads/dalvik.vm.boot-dex2oat-cpu-set
      • (至 Android 11 為止) 在啟動期間,除了啟動映像檔以外,所有項目都會使用此執行緒數量和 CPU 核心集合 (請見下方說明)。
      • (自 Android 12 起) 在啟動期間要使用的執行緒數量和 CPU 核心集合 (請參閱下方說明),包括啟動映像檔。
        • 具體來說,自 Android 14 起,這會對應至 ART 服務中的優先順序類別 PRIORITY_BOOT
    • dalvik.vm.restore-dex2oat-threads/dalvik.vm.restore-dex2oat-cpu-set
      • (自 Android 11 起,直到 Android 13) 從雲端備份還原時要使用的執行緒數和 CPU 核心集合 (請參閱下方說明)。
      • (自 Android 14 起) 針對比一般情況更容易受到延遲影響的所有作業 (包括從雲端備份還原),可使用的執行緒數和 CPU 核心組合 (請見下文)。
        • 具體來說,這會對應至 ART 服務中的優先順序類別 PRIORITY_INTERACTIVE_FAST
    • dalvik.vm.background-dex2oat-threads/ dalvik.vm.background-dex2oat-cpu-set (自 Android 14 起):在背景中使用的執行緒數量和 CPU 核心集合 (請參閱下文)。
      • 具體來說,這會對應至 ART 服務中的 PRIORITY_BACKGROUND 優先順序類別。
    • dalvik.vm.dex2oat-threads/dalvik.vm.dex2oat-cpu-set:其他所有項目要使用的執行緒數量和 CPU 核心組合。

    一組 CPU 核心應指定為以半形逗號分隔的 CPU ID 清單。舉例來說,如要在 CPU 核心 0 至 3 上執行 dex2oat,請設定:

    dalvik.vm.dex2oat-cpu-set=0,1,2,3
    

    設定 CPU 相依性屬性時,建議您將 dex2oat 執行緒數量的對應屬性與所選 CPU 數量相符,以免發生不必要的記憶體和 I/O 競爭:

    dalvik.vm.dex2oat-cpu-set=0,1,2,3
    dalvik.vm.dex2oat-threads=4
    

    除了上述系統屬性外,您也可以使用工作設定檔來控管 dex2oat 的資源使用情形 (請參閱「Cgroup 抽象層」)。

    支援的工作設定檔如下:

    • Dex2OatBackground (自 Android 14 起) (預設會繼承 Dex2OatBootComplete): 控管在背景中使用的資源。
      • 具體來說,這會對應至 ART 服務中的優先順序類別 PRIORITY_BACKGROUND
    • Dex2OatBootComplete
      • (至 Android 13 為止) 控制啟動後所有項目要使用的資源。
      • (自 Android 14 起) 控制在啟動後,所有非背景作業使用的資源。
        • 具體來說,這會對應至 ART 服務中的優先順序類別 PRIORITY_INTERACTIVE_FASTPRIORITY_INTERACTIVE

    系統屬性和工作設定檔都指定後,兩者都會生效。

    用於控制堆積大小的選項:

    • dalvik.vm.image-dex2oat-Xms:啟動映像檔的初始堆積大小。
    • dalvik.vm.image-dex2oat-Xmx:啟動映像檔的堆積大小上限。
    • dalvik.vm.dex2oat-Xms:其他所有項目的初始堆積大小。
    • dalvik.vm.dex2oat-Xmx:其他所有項目的堆積大小上限。

    請勿減少控制 dex2oat 初始堆積大小和最大堆積大小的選項,因為這可能會限制可編譯的應用程式。

    控制編譯器篩選器的選項:

    • dalvik.vm.image-dex2oat-filter (至 Android 11 為止):啟動映像檔的編譯器篩選器。自 Android 12 起,啟動映像檔的編譯器篩選器一律為 speed-profile,且無法變更。
    • dalvik.vm.systemservercompilerfilter (自 Android 13 起):系統伺服器的編譯器篩選器。請參閱 PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
    • dalvik.vm.systemuicompilerfilter (自 Android 13 起):系統 UI 套件的編譯器篩選器。
    • dalvik.vm.dex2oat-filter (至 Android 6 為止):編譯器篩選器,用於篩選其他所有項目。
    • pm.dexopt.<reason> (自 Android 7 起):其他所有項目的編譯器篩選器。如要瞭解 Android 14 以上版本的 ART 服務設定,請參閱「ART 服務設定」;如要瞭解 Android 13 以下版本的 Package Manager 設定,請參閱「Package Manager 設定」。

    其他選項可用於控制引導映像檔以外的所有項目的編譯作業:

    • dalvik.vm.dex2oat-very-large (自 Android 7.1 起):以位元組為單位的最低 DEX 檔案總大小,用於停用 AOT 編譯。
    • dalvik.vm.dex2oat-swap (自 Android 7.1 起) (預設值:true):允許使用 Swap 檔案進行 dex2oat。這有助於避免記憶體不足而導致應用程式異常終止。請注意,即使已啟用此選項,dex2oat 仍只會在特定情況下使用 Swap 檔案,例如 dex 檔案數量龐大時,且情況可能會有所變動。
    • dalvik.vm.ps-min-first-save-ms (自 Android 12 起):在首次啟動應用程式時,執行階段產生應用程式設定檔前,必須等待的最短時間。
    • dalvik.vm.ps-min-save-period-ms (自 Android 12 起):更新應用程式設定檔前,必須等待的最短時間。
    • dalvik.vm.dex2oat64.enabled (自 Android 11 起) (預設值:false):是否使用 64 位元版本的 dex2oat。
    • dalvik.vm.bgdexopt.new-classes-percent (自 Android 12 起) (預設值:20): 設定檔中新類別的最低百分比 (介於 0 和 100 之間),用於觸發重新編譯作業。僅適用於設定檔引導的編譯作業 (speed-profile),通常是在背景 dexopt 期間。請注意,除了百分比門檻外,還有至少 50 個新類別的門檻,且無法設定。
    • dalvik.vm.bgdexopt.new-methods-percent (自 Android 12 起) (預設值:20): 設定檔中新方法的最低百分比 (介於 0 和 100 之間),用於觸發重新編譯。僅適用於設定檔引導的編譯作業 (speed-profile),通常是在背景 dexopt 期間。請注意,除了百分比門檻外,還有至少 100 個新方法的門檻,且無法設定。
    • dalvik.vm.dex2oat-max-image-block-size (自 Android 10 起) (預設值:524288) 壓縮圖片的最大實心區塊大小。大型圖片會拆分為一組實心區塊,以便確保每個區塊的大小不超過上限。
    • dalvik.vm.dex2oat-resolve-startup-strings (自 Android 10 起) (預設值:true) 如果為 true,dex2oat 會解析從在設定檔中標示為「startup」的方法參照的所有 const 字串。
    • debug.generate-debug-info (預設值:false) 是否產生原生偵錯的偵錯資訊,例如堆疊解開資訊、ELF 符號和矮人區段。
    • dalvik.vm.dex2oat-minidebuginfo (自 Android 9 起) (預設值:true) 是否要產生最少量的 LZMA 壓縮偵錯資訊,以便列印回溯追蹤。

    ART 服務選項

    自 Android 14 起,應用程式在裝置上的預先編譯作業 (又稱為 dexopt) 會由 ART 服務處理。如要瞭解如何設定 ART 服務,請參閱「ART 服務設定」一文。

    套件管理工具選項

    在 Android 14 之前,應用程式的裝置端 AOT 編譯作業 (又稱為 dexopt) 由套件管理工具處理。如要瞭解如何設定 dexopt 的套件管理工具,請參閱「套件管理工具設定」。

    A/B 專屬設定

    ROM 設定

    從 Android 7.0 開始,裝置可能會使用兩個系統分區來啟用 A/B 系統更新。為節省系統分割區大小,預先選取的檔案可安裝在未使用的第二個系統分割區。然後在首次啟動時複製到資料分區。

    使用範例 (在 device-common.mk 中):

    PRODUCT_PACKAGES += \
         cppreopts.sh
    PRODUCT_PROPERTY_OVERRIDES += \
         ro.cp_system_other_odex=1
    

    在裝置的 BoardConfig.mk 中:

    BOARD_USES_SYSTEM_OTHER_ODEX := true
    

    請注意,啟動 classpath 程式碼、系統伺服器程式碼和產品專屬核心應用程式一律會編譯至系統分區。根據預設,所有其他應用程式都會編譯至未使用的第二個系統分區。您可以使用 SYSTEM_OTHER_ODEX_FILTER 控制這項功能,其預設值為:

    SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
    

    背景 OTA dexopt

    在啟用 A/B 的裝置上,應用程式可以在背景編譯,然後重新啟動並使用新的系統映像檔。請參閱「在背景中編譯應用程式」,選擇是否要在系統映像檔中加入編譯指令碼和二進位檔。用於此編譯作業的編譯篩選器可透過下列方式控制:

    pm.dexopt.ab-ota=speed-profile
    

    建議您使用 speed-profile,充分運用設定檔引導的編譯作業,並節省儲存空間。

    JDWP 選項

    在使用者偵錯版本中,Java 偵錯傳輸線協定 (JDWP) 執行緒建立作業會透過 persist.debug.dalvik.vm.jdwp.enabled 系統屬性控制。根據預設,這項屬性不會設為已設定,且 JDWP 執行緒只會為可偵錯的應用程式建立。如要為可偵錯和不可偵錯的應用程式啟用 JDWP 執行緒,請將 persist.debug.dalvik.vm.jdwp.enabled 設為 1。裝置必須重新啟動,屬性變更才會生效。

    如要在 userdebug 版本上偵錯無法偵錯的應用程式,請執行下列指令啟用 JDWP:

      adb shell setprop persist.debug.dalvik.vm.jdwp.enabled 1
      adb reboot
      
    對於搭載 Android 13 以下版本的裝置,在 userdebug 版本中,執行階段會為可偵錯和不可偵錯的應用程式建立 JDWP 執行緒。也就是說,您可以在 userdebug 版本中附加偵錯工具或剖析任何應用程式。