Domanda

Che cosa rende esattamente lenta la JVM (in particolare l'implementazione di Sun) rispetto ad altri runtime come CPython? La mia impressione è stata che ha a che fare principalmente con un carico di librerie caricate indipendentemente dal fatto che siano necessarie o meno, ma sembra qualcosa che non dovrebbe richiedere 10 anni per essere riparato.

Vieni a pensarci bene, come si confronta l'ora di inizio di JVM con il CLR su Windows? Che ne dici di Mono CLR?

AGGIORNAMENTO: Mi occupo in particolare del caso d'uso di piccole utility concatenate come è comune in Unix. Java è ora adatto a questo stile? Qualunque sia il sovraccarico di avvio di Java, si somma per ogni processo Java o l'overhead si manifesta solo per il primo processo?

È stato utile?

Soluzione

Ecco ciò che Wikipedia ha da dire sulla questione (con alcuni riferimenti) .

Sembra che la maggior parte del tempo venga impiegata semplicemente caricando i dati (classi) dal disco (ovvero il tempo di avvio è associato all'I / O).

Altri suggerimenti

Solo per notare alcune soluzioni:

Esistono due meccanismi che consentono un avvio più rapido della JVM. Il primo è il meccanismo di condivisione dei dati di classe, supportato dall'aggiornamento 21 di Java 6 (solo con la VM client HotSpot e solo con il garbage collector seriale per quanto ne so)

Per attivarlo devi impostare -Xshare (su alcune implementazioni: -Xshareclasses ) Opzioni JVM.

Per saperne di più sulla funzione che puoi visitare: Condivisione dati classe

Il secondo meccanismo è un Quick Starter Java. Permette di precaricare le classi durante l'avvio del sistema operativo, vedere: Java Quick Starter per maggiori dettagli.

L'esecuzione di una banale app Java con il client 1.6 (Java 6) JVM sembra istantanea sulla mia macchina. Sun ha tentato di ottimizzare il client JVM per un avvio più rapido (e il client JVM è l'impostazione predefinita), quindi se non hai bisogno di molti file jar aggiuntivi, l'avvio dovrebbe essere rapido.

Se si utilizza HotSpot di Sun per x86_64 (compilato a 64 bit), tenere presente che l'implementazione corrente funziona solo in modalità server, ovvero precompila ogni classe caricata con ottimizzazione completa, mentre la versione a 32 bit supporta anche la modalità client, che generalmente posticipa l'ottimizzazione e ottimizza solo le parti che richiedono più CPU, ma ha tempi di avvio più rapidi.

Vedi ad esempio:

Detto questo, almeno sulla mia macchina (Linux x86_64 con kernel a 64 bit), la versione HotSpot a 32 bit supporta la modalità client e server (tramite i flag -client e -server), ma per impostazione predefinita è la modalità server, mentre la 64 bit la versione supporta solo la modalità server.

Dipende davvero da cosa stai facendo durante l'avvio. Se esegui l'applicazione Hello World sono necessari 0,15 secondi sul mio computer.

Tuttavia, Java è più adatto all'esecuzione come client o server / servizio, il che significa che il tempo di avvio non è importante quanto il tempo di connessione (circa 0,025 ms) o il tempo di risposta di andata e ritorno (< ; < 0,001 ms).

Esistono diversi motivi:

  • molti jar s da caricare
  • verifica (assicurandosi che il codice non faccia cose cattive)
  • spese generali JIT (compilazione just in time)

Non sono sicuro del CLR, ma penso che sia spesso più veloce perché memorizza nella cache una versione nativa di assiemi per la prossima volta (quindi non ha bisogno di JIT). CPython si avvia più velocemente perché è un interprete e IIRC non esegue JIT.

Oltre alle cose già menzionate (caricamento di classi, in particolare da JAR compressi); in esecuzione in modalità interpretata prima che HotSpot compili il bytecode comunemente usato; e sovraccarico di compilazione di HotSpot, c'è anche un po 'di inizializzazione una tantum effettuata dalle stesse classi JDK. Molte ottimizzazioni vengono fatte a favore di sistemi a esecuzione più lunga in cui la velocità di avvio è meno preoccupante.

E per unire le pipeline di stile: di certo NON si desidera avviare e riavviare JVM più volte. Non sarà efficiente. Piuttosto il concatenamento di strumenti dovrebbe avvenire all'interno di JVM. Questo non può essere facilmente mescolato con strumenti Unix non Java, tranne avviando tali strumenti da JVM.

Tutte le VM con un sistema di tipo avanzato come Java o CLR non saranno istantanee rispetto a sistemi meno ricchi come quelli trovati in C o C ++. Ciò è in gran parte dovuto al fatto che molte cose stanno accadendo nella VM, molte classi vengono inizializzate e sono richieste da un sistema in esecuzione. Le istantanee di un sistema inizializzato sono utili, ma costa comunque caricare di nuovo l'immagine in memoria, ecc.

Un semplice ciao in stile one liner class con un main richiede ancora molto da caricare e inizializzare. La verifica della classe richiede molto controllo e convalida delle dipendenze, tutto ciò che richiede tempo e molte istruzioni della CPU da eseguire. D'altro canto, un programma C non eseguirà nessuna di queste operazioni e comporterà alcune istruzioni e quindi invocherà la funzione stampante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top