Google 致力于为黑人社区推动种族平等。查看具体举措
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Configurazione di ART

Questa pagina discute come configurare ART e le sue opzioni di compilazione. Gli argomenti affrontati qui includono la configurazione della precompilazione dell'immagine di sistema, le opzioni di compilazione di dex2oat e come compensare lo spazio della partizione di sistema, lo spazio della partizione dati e le prestazioni.

Vedere ART e Dalvik , il formato eseguibile Dalvik e le pagine rimanenti su source.android.com per lavorare con ART. Consulta Verifica del comportamento delle app sul runtime Android (ART) per assicurarti che le tue app funzionino correttamente.

Come funziona ART

ART utilizza la compilazione anticipata (AOT) e, a partire da Android 7.0 (Nougat o N), utilizza una combinazione ibrida di AOT, compilazione just-in-time (JIT) e compilazione guidata dal profilo. La combinazione di tutte queste modalità di compilazione è configurabile e verrà discussa in questa sezione. Ad esempio, i dispositivi Pixel vengono configurati con il seguente flusso di compilazione:

  1. Un'applicazione viene inizialmente installata senza alcuna compilazione AOT. Le prime volte che l'applicazione viene eseguita, verrà interpretata ei metodi eseguiti di frequente verranno compilati JIT.
  2. Quando il dispositivo è inattivo e in carica, viene eseguito un demone di compilazione per compilare AOT il codice utilizzato di frequente in base a un profilo generato durante le prime esecuzioni.
  3. Il successivo riavvio di un'applicazione utilizzerà il codice guidato dal profilo ed eviterà di eseguire la compilazione JIT in fase di esecuzione per i metodi già compilati. I metodi che vengono compilati con JIT durante le nuove esecuzioni verranno aggiunti al profilo, che verrà quindi rilevato dal demone di compilazione.

ART comprende un compilatore (lo strumento dex2oat ) e un runtime ( libart.so ) che viene caricato per l'avvio di Zygote. Lo strumento dex2oat prende un file APK e genera uno o più file di artefatti di compilazione caricati dal runtime. Il numero di file, le loro estensioni e i nomi sono soggetti a modifiche tra le versioni, ma a partire dalla versione di Android O, i file generati sono:

  • .vdex : contiene il codice DEX non compresso .vdex , con alcuni metadati aggiuntivi per velocizzare la verifica.
  • .odex : contiene il codice compilato AOT per i metodi .odex .
  • .art (optional) : contiene rappresentazioni interne ART di alcune stringhe e classi elencate nell'APK, utilizzate per velocizzare l'avvio dell'applicazione.

Opzioni di compilazione

Le opzioni di compilazione per ART sono di due categorie:

  1. Configurazione della ROM di sistema: quale codice viene compilato da AOT durante la creazione di un'immagine di sistema.
  2. Configurazione runtime: come ART compila ed esegue le applicazioni su un dispositivo.

Una delle opzioni principali di ART per configurare queste due categorie sono i filtri del compilatore . I filtri del compilatore guidano il modo in cui ART compila il codice DEX ed è un'opzione passata allo strumento dex2oat . A partire da Android O, ci sono quattro filtri ufficialmente supportati:

  • verifica : esegui solo la verifica del codice DEX.
  • accelera : esegui la verifica del codice DEX e ottimizza alcune istruzioni DEX per ottenere migliori prestazioni dell'interprete.
  • velocità : esegui la verifica del codice DEX e AOT-compila tutti i metodi.
  • speed-profile : esegui la verifica del codice DEX e i metodi di compilazione AOT elencati in un file di profilo.

Configurazione della ROM di sistema

Sono disponibili numerose opzioni di build ART per la configurazione di una ROM di sistema. La modalità di configurazione di queste opzioni dipende dallo spazio di archiviazione disponibile per /system e dal numero di applicazioni preinstallate. I JAR / APK compilati in una ROM di sistema possono essere suddivisi in quattro categorie:

  • Codice percorso classe di avvio: compilato con il filtro del compilatore di velocità per impostazione predefinita.
  • Codice del server di sistema: compilato con il filtro del compilatore di velocità per impostazione predefinita.
  • Applicazioni principali specifiche del prodotto: compilate con il filtro del compilatore di velocità per impostazione predefinita.
  • Tutte le altre applicazioni: compilate con il filtro del compilatore quicken per impostazione predefinita.

Opzioni makefile

  • WITH_DEXPREOPT
  • Indica se dex2oat viene richiamato sul codice DEX installato sull'immagine di sistema. Abilitato per impostazione predefinita.

  • DONT_DEXPREOPT_PREBUILTS (da Android L)
  • L'abilitazione di DONT_DEXPREOPT_PREBUILTS impedisce la pre-ottimizzazione dei pre-ottimizzati. Si tratta di app che include $(BUILD_PREBUILT) specificato nel loro Android.mk , come Gmail. Saltare la pre-ottimizzazione delle app predefinite che potrebbero essere aggiornate tramite Google Play consente di risparmiare /system spazio di /system ma si aggiunge al primo avvio.

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (da Android 9)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER specifica il filtro del compilatore predefinito per le applicazioni pre-ottimizzate. Si tratta di app che include $(BUILD_PREBUILT) specificato nel loro Android.mk , come Gmail. Se non specificato, il valore predefinito è quicken.

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (nuovo in Android O MR1)
  • L'abilitazione di WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY pre-ottimizza solo il percorso WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY avvio e i jar del server di sistema.

  • LOCAL_DEX_PREOPT
  • La pre-ottimizzazione può anche essere abilitata o disabilitata su una singola app specificando l'opzione LOCAL_DEX_PREOPT nella definizione del modulo. Ciò può essere utile per disabilitare la pre-ottimizzazione delle app che potrebbero ricevere immediatamente gli aggiornamenti di Google Play poiché gli aggiornamenti renderebbero obsoleto il codice pre-ottimizzato nell'immagine di sistema. Ciò è utile anche per risparmiare spazio sulle OTA di aggiornamento della versione principale poiché gli utenti potrebbero già avere versioni più recenti delle app nella partizione dati.

    LOCAL_DEX_PREOPT supporta i valori "true" o "false" rispettivamente per abilitare o disabilitare la pre-ottimizzazione. Inoltre, è possibile specificare "nostripping" se la pre-ottimizzazione non deve classes.dex file classes.dex dal file APK o JAR. Normalmente questo file viene rimosso poiché non è più necessario dopo la pre-ottimizzazione, ma quest'ultima opzione è necessaria per consentire alle firme APK di terze parti di rimanere valide.

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • Passa le opzioni a dex2oat per controllare come viene compilata l'immagine di avvio. Può essere utilizzato per specificare elenchi di classi di immagini personalizzate, elenchi di classi compilate e filtri del compilatore.

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • Passa le opzioni a dex2oat per controllare come viene compilato tutto tranne l'immagine di avvio.

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • Fornisce la capacità di passare dex2oat opzioni dex2oat per un particolare modulo e configurazione del prodotto. È impostato nel file device.mk un prodotto da $(call add-product-dex-preopt-module-config,<modules>,<option>) dove <modules> è un elenco di nomi LOCAL_MODULE e LOCAL_PACKAGE per JAR e APK file, rispettivamente.

  • PRODUCT_DEXPREOPT_SPEED_APPS (New in Android O)
  • Elenco delle applicazioni che sono state identificate come core dei prodotti e che è opportuno compilare con il filtro del compilatore di velocità . Ad esempio, le app persistenti come SystemUI hanno la possibilità di utilizzare la compilazione guidata dal profilo solo al successivo riavvio, quindi potrebbe essere meglio per il prodotto avere queste app sempre compilate AOT.

  • PRODUCT_SYSTEM_SERVER_APPS (New in Android O)
  • Elenco delle applicazioni caricate dal server di sistema. Queste applicazioni verranno compilate per impostazione predefinita con il filtro del compilatore di velocità .

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD(Post Android O)
  • Se includere una versione di debug di ART sul dispositivo. Per impostazione predefinita, questo è abilitato per le build userdebug e eng. Il comportamento può essere sovrascritto impostando esplicitamente l'opzione su true o false .

    Per impostazione predefinita, il dispositivo utilizzerà la versione non di debug ( libart.so ). Per cambiare, impostare la proprietà di sistema persist.sys.dalvik.vm.lib.2 su libartd.so .

  • WITH_DEXPREOPT_PIC (Removed in Android O)
  • In Android 5.1.0 e Android 6.0.1, WITH_DEXPREOPT_PIC può essere specificato per abilitare il codice indipendente dalla posizione (PIC). Con questo, il codice compilato dall'immagine non deve essere riposizionato da / system in / data / dalvik-cache, risparmiando spazio nella partizione dati. Tuttavia, c'è un leggero impatto sul runtime perché disabilita un'ottimizzazione che sfrutta il codice dipendente dalla posizione. In genere, i dispositivi che desiderano risparmiare spazio in / data dovrebbero abilitare la compilazione PIC.

    In Android 7.0, la compilazione PIC era abilitata per impostazione predefinita.

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (rimosso in Android O MR1)
  • Questa opzione è stata sostituita con WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY che precede anche i jar del server di sistema.

Configurazione del percorso di classe di avvio

  • Elenco classi precaricato
  • L'elenco delle classi precaricate è un elenco di classi che lo zygote inizializzerà all'avvio. Ciò evita che ogni app debba eseguire questi inizializzatori di classe separatamente, consentendo loro di avviarsi più velocemente e condividere pagine in memoria. Il file dell'elenco delle classi precaricato si trova in frameworks / base / preloaded-classes per impostazione predefinita e contiene un elenco ottimizzato per l'uso tipico del telefono. Potrebbe essere diverso per altri dispositivi, come i dispositivi indossabili, e dovrebbe essere regolato di conseguenza. Fare attenzione durante la regolazione poiché l'aggiunta di troppe classi spreca memoria nel caricamento delle classi inutilizzate; nel frattempo, aggiungerne troppo poche obbliga ogni app ad avere la propria copia, sprecando nuovamente memoria.

    Esempio di utilizzo (in device.mk del prodotto):

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

    Nota: questa riga deve essere inserita prima di ereditare qualsiasi makefile di configurazione del prodotto che ottiene quello predefinito da: build/target/product/base.mk

  • Elenco classi di immagini
  • L'elenco delle classi di immagini è un elenco di classi che dex2oat inizializza in anticipo e memorizza nel file boot.art. Ciò consente allo zygote di caricare questi risultati dal file boot.art all'avvio invece di eseguire gli inizializzatori per queste classi durante il precaricamento. Una caratteristica fondamentale di questo è che le pagine caricate dall'immagine e condivise tra i processi possono essere pulite, consentendo loro di essere sostituite facilmente in situazioni di scarsa memoria. In L, per impostazione predefinita, l'elenco delle classi di immagini utilizza lo stesso elenco dell'elenco delle classi precaricate. A partire dal post-L in AOSP, è possibile specificare un elenco di classi di immagini personalizzate utilizzando:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Esempio di utilizzo (nel dispositivo device.mk del prodotto):

    PRODUCT_DEX_PREOPT_BOOT_FLAGS += --image-classes=<filename>
    
  • Elenco delle classi compilato
  • Nell'AOSP post-L, è possibile specificare un sottoinsieme di classi dal classpath di avvio da compilare durante la pre-ottimizzazione utilizzando l'elenco delle classi compilato. Questa può essere un'opzione utile per i dispositivi che hanno poco spazio e non possono adattarsi all'intera immagine di avvio pre-ottimizzata. Tuttavia, le classi di note non specificate da questo elenco non verranno compilate, nemmeno sul dispositivo, e devono essere interpretate, influendo potenzialmente sulle prestazioni di runtime. Per impostazione predefinita, dex2oat cercherà un elenco di classi compilato in $ OUT / system / etc / compiled-classes, quindi uno personalizzato può essere copiato in quella posizione da device.mk. È inoltre possibile specificare un percorso di file particolare utilizzando:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Esempio di utilizzo (in device.mk del prodotto):

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

    Nota: questa riga deve essere inserita prima di ereditare qualsiasi makefile di configurazione del prodotto che ottiene quello predefinito da: build/target/product/base.mk

Configurazione runtime

Opzioni Jit

Le seguenti opzioni influiscono sulle versioni Android solo in cui è disponibile il compilatore ART JIT.

  • dalvik.vm.usejit: se il JIT è abilitato o meno.
  • dalvik.vm.jitinitialsize (default 64K): la capacità iniziale della cache del codice. La cache del codice verrà regolarmente GC e aumenterà se necessario.
  • dalvik.vm.jitmaxsize (default 64M): la capacità massima della cache del codice.
  • dalvik.vm.jitthreshold: (default 10000) - Questa è la soglia che il contatore "hotness" di un metodo deve superare affinché il metodo possa essere compilato JIT. Il contatore "hotness" è una metrica interna al runtime. Include il numero di chiamate, le diramazioni a ritroso e altri fattori.
  • dalvik.vm.usejitprofiles: se i profili JIT sono abilitati o meno; questo può essere utilizzato anche se dalvik.vm.usejit è falso. Nota che se questo è falso, il profilo di velocità del filtro del compilatore non compila AOT alcun metodo ed è equivalente a velocizzare .
  • dalvik.vm.jitprithreadweight (il valore predefinito è dalvik.vm.jitthreshold / 20) - Il peso dei "campioni" JIT (vedere jitthreshold) per il thread dell'interfaccia utente dell'applicazione. Utilizzare per velocizzare la compilazione di metodi che influenzano direttamente l'esperienza degli utenti durante l'interazione con l'app.
  • dalvik.vm.jittransitionweight: (predefinito su dalvik.vm.jitthreshold / 10) il peso dell'invocazione del metodo che passa tra il codice di compilazione e l'interprete. Questo aiuta a garantire che i metodi coinvolti siano compilati per ridurre al minimo le transizioni (che sono costose).

Opzioni del gestore dei pacchetti

A partire da Android 7.0, esiste un modo generico per specificare il livello di compilazione / verifica che si è verificato in varie fasi. I livelli di compilazione possono essere configurati tramite le proprietà di sistema con i valori predefiniti:

  • pm.dexopt.install = accelera
  • Questo è il filtro di compilazione utilizzato durante l'installazione di applicazioni tramite Google Play. Per installazioni più veloci, prova il filtro del compilatore quicken .

  • pm.dexopt.bg-dexopt = profilo di velocità
  • Questo è il filtro di compilazione utilizzato quando il dispositivo è inattivo, in carica e completamente carico. Prova il filtro del compilatore del profilo di velocità per sfruttare la compilazione guidata dal profilo e risparmiare sullo spazio di archiviazione.

  • pm.dexopt.boot = verifica
  • Il filtro di compilazione utilizzato dopo un aggiornamento over-the-air. Consigliamo vivamente il filtro del compilatore di verifica per questa opzione per evitare tempi di avvio molto lunghi.

  • pm.dexopt.first-boot = accelera
  • Il filtro di compilazione per la prima volta che il dispositivo si avvia. Il filtro utilizzato qui influenzerà solo il tempo di avvio dopo la fabbrica. Si consiglia di accelerare il filtro per evitare lunghi tempi prima che un utente possa utilizzare il telefono per la prima volta. Si noti che se tutte le applicazioni in /system sono già compilate con il filtro del compilatore quicken o sono compilate con il filtro del compilatore speed o speed-profile , pm.dexopt.first-boot non ha effetto.

Opzioni di Dex2oat

Nota che queste opzioni influenzano dex2oat durante la compilazione sul dispositivo così come durante la pre-ottimizzazione, mentre la maggior parte delle opzioni discusse sopra influenzano solo la pre-ottimizzazione.

Per controllare dex2oat mentre sta compilando l'immagine di avvio:

  • dalvik.vm.image-dex2oat-Xms: dimensione heap iniziale
  • dalvik.vm.image-dex2oat-Xmx: dimensione massima dell'heap
  • dalvik.vm.image-dex2oat-filter: opzione del filtro del compilatore
  • dalvik.vm.image-dex2oat-threads: numero di thread da usare

Per controllare dex2oat mentre sta compilando tutto tranne l'immagine di avvio:

  • dalvik.vm.dex2oat-Xms: dimensione heap iniziale
  • dalvik.vm.dex2oat-Xmx: dimensione massima dell'heap
  • dalvik.vm.dex2oat-filter: opzione di filtro del compilatore

Nelle versioni tramite Android 6.0, viene fornita un'opzione aggiuntiva per compilare tutto oltre all'immagine di avvio:

  • dalvik.vm.dex2oat-thread: numero di thread da utilizzare

A partire da Android 6.1, queste diventano due opzioni aggiuntive per compilare tutto oltre all'immagine di avvio:

  • dalvik.vm.boot-dex2oat-thread: numero di thread da utilizzare durante l'avvio
  • dalvik.vm.dex2oat-thread: numero di thread da utilizzare dopo l'avvio

A partire da Android 7.1, sono disponibili due opzioni per controllare come viene utilizzata la memoria durante la compilazione di tutto tranne l'immagine di avvio:

  • dalvik.vm.dex2oat-very-large: dimensione minima del file dex totale in byte per disabilitare la compilazione AOT
  • dalvik.vm.dex2oat-swap: usa il file di scambio dex2oat (per dispositivi con poca memoria)

Le opzioni che controllano la dimensione iniziale e massima dell'heap per dex2oat non dovrebbero essere ridotte poiché potrebbero limitare le applicazioni che possono essere compilate.

A partire da Android 11, vengono fornite tre opzioni di affinità CPU per consentire ai thread del compilatore di essere limitati a un gruppo specifico di CPU:

  • dalvik.vm.boot-dex2oat-cpu-set: CPU che eseguono thread dex2oat durante l'avvio
  • dalvik.vm.image-dex2oat-cpu-set: CPU che eseguono dex2oat durante la compilazione dell'immagine di avvio
  • dalvik.vm.dex2oat-cpu-set: CPU che eseguono thread dex2oat dopo l'avvio

Le CPU devono essere specificate come un elenco separato da virgole di ID CPU. Ad esempio per eseguire su dex2oat sulle CPU 0-3, impostare:

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

Quando si impostano le proprietà di affinità CPU, si consiglia di abbinare la proprietà corrispondente per il numero di thread dex2oat al numero di CPU selezionate per evitare memoria non necessaria e conflitti di I / O:

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

Configurazione specifica A / B

Configurazione ROM

A partire da Android 7.0, i dispositivi possono utilizzare due partizioni di sistema per abilitare gli aggiornamenti di sistema A / B. Per risparmiare sulle dimensioni della partizione di sistema, i file preoptati possono essere installati nella seconda partizione di sistema inutilizzata. Vengono quindi copiati nella partizione dati al primo avvio.

Esempio di utilizzo (in device-common.mk ):

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

E nel BoardConfig.mk del dispositivo:

BOARD_USES_SYSTEM_OTHER_ODEX := true

Notare che il codice del percorso di classe di avvio, il codice del server di sistema e le applicazioni principali specifiche del prodotto vengono compilati sempre nella partizione di sistema. Per impostazione predefinita, tutte le altre applicazioni vengono compilate nella seconda partizione di sistema inutilizzata. Questo può essere controllato con SYSTEM_OTHER_ODEX_FILTER , che ha un valore predefinito di:

SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%

Sfondo dexopt OTA

Con i dispositivi abilitati A / B, le applicazioni possono essere compilate in background per l'aggiornamento alla nuova immagine di sistema. Vedere Compilazione di app in background per includere facoltativamente lo script di compilazione e i file binari nell'immagine di sistema. Il filtro di compilazione utilizzato per questa compilation è controllato con:

pm.dexopt.ab-ota=speed-profile

Si consiglia di utilizzare speed-profile per sfruttare la compilazione guidata del profilo e risparmiare sull'archiviazione.