2012-05-23 9 views
8

I ProGuard liste home page come caratteristica:Cosa c'è di più veloce nel caricamento di classi Java 6?

  • retargeting e preverifying file di classe esistenti per Java 6, a prendere appieno classe caricamento più veloce di Java 6.

Qual è la differenza in Java 6 a cui questo si riferisce?

E significativo?

Ha un impatto sui rallentamenti causati dal multithreading tramite gli aspetti sincronizzati del classloader predefinito?

+1

Potrebbe riferirsi a questo: http://java.sun.com/performance/reference/whitepapers/6_performance.html#2.4.2 – assylias

risposta

2

Come il ProGuardFAQ hints:

il compilatore Java 6 aggiungere informazioni preverification ai file di classe

Guardando allo Java Virtual Machine SpecificationVerification by Type Checking sezione:

Se un'implementazione Java virtual machine tenta sempre di eseguire la verifica da parte di inferenza su file di classe versione 50.0, si deve farlo in tutti i casi in cui la verifica da typechecking fallisce.

Ciò significa che un'implementazione di una macchina virtuale Java non può scegliere di ricorrere all'inferenza di tipo in un caso e non in un altro. Deve rifiutare i file di classe che non vengono verificati tramite typechecking, oppure eseguire in modo coerente il failover al verificatore di inferenza del tipo ogni volta che typechecking fallisce.

Il controllo di tipo richiede un elenco di frame di stack map per ogni metodo con un attributo Code. Il controllo del tipo legge i frame di stack map per ciascun metodo e utilizza queste mappe per generare una prova del tipo safety delle istruzioni nell'attributo Code.

Cominciando con Java 6, file di classe 50.0 e superiori, una JVM può utilizzare la verifica del tipo o inferenza di tipo durante la verifica file di classe. Prima di provare a capire i benefici in termini di prestazioni, che cos'è il controllo dei tipi e l'inferenza del tipo? Questo documento, Type-Checking and Type-Inference for Object-Oriented Programming Languages dichiara:

Un sistema di tipo è una parte importante di un linguaggio di programmazione. Le lingue che si basano completamente sul controllo dei tipi di runtime forniscono un alto grado di flessibilità, ma di solito devono sacrificare le prestazioni per farlo.

E da Wikipedia su Type inference:

inferenza di tipo è la capacità di dedurre automaticamente, parzialmente o totalmente, il tipo di un'espressione in fase di compilazione. [...]

Per ottenere le informazioni richieste per inferire il tipo di un'espressione, il compilatore raccoglie queste informazioni come un aggregato e una successiva riduzione delle annotazioni di tipo fornite per le sue sottoespressioni, o attraverso una comprensione implicita del tipo di vari valori atomici [...].

Il OpenJDK HotSport Runtime Overview lo spiega bene:

Attualmente vi sono due metodi di analisi dei bytecode per determinare il tipo e il numero di operandi che saranno presenti per ogni istruzione. Il metodo tradizionale è chiamato "tipo inferenza" e opera eseguendo un'interpretazione astratta di ciascun codice byte e degli stati del tipo di unione in corrispondenza di destinazioni di ramo o handle di eccezioni. L'analisi esegue iterazioni sul bytecode finché non viene trovato uno stato stazionario per i tipi. Se non è possibile trovare uno stato stazionario o se i tipi risultanti violano qualche vincolo bytecode, viene generato un VerifyError. [...]

Novità in JDK6 è il secondo metodo di verifica che si chiama "verifica del tipo". In questo metodo il compilatore Java fornisce le informazioni sul tipo a stato stazionario per ogni ramo o destinazione dell'eccezione, tramite l'attributo code StackMapTable. StackMapTable è costituito da un numero di frame di stack map, ciascuno dei quali indica i tipi di elementi nello stack di espressioni e nelle variabili locali con un certo offset nel metodo. La JVM deve quindi eseguire solo un passaggio attraverso il bytecode per verificare la correttezza dei tipi per verificare il bytecode. [...]

Controllo del tipo: la JVM può eseguire un passaggio attraverso il file di classe per verificare il sistema di tipi; l'inferenza del tipo richiede più passaggi. Si tratta di un notevole risparmio di prestazioni? Probabilmente è relativo al numero totale di classi che hai nella tua applicazione e al numero di file di classe che hai meno di 50.0 (Java 6) e 50.0 e versioni successive. Se la tua applicazione non è un'applicazione performante, non me ne preoccuperei; in tal caso, è possibile eseguire alcuni benchmark confrontando le differenze di prestazioni durante la compilazione dell'applicazione su file di classe Java 5 e Java 6.

2

Il miglioramento, secondo this Java 6 white paper è:

di avvio e di classe estensione caricatori della macchina virtuale Java sono stati migliorati per migliorare il tempo di avviamento a freddo di applicazioni Java. Prima di Java SE 6, l'apertura del file jar di sistema causava alla Java Virtual Machine la lettura di un file di indice ZIP da 1 megabyte che veniva convertito in un gran numero di attività di ricerca disco quando il file non era nella cache del disco. Con "condivisione dati classe" abilitata, la Java Virtual Machine viene ora fornita con un file "meta-index" (situato in jre/lib) che contiene informazioni di alto livello su quali pacchetti (o prefissi di pacchetto) sono contenuti in cui i file jar.

Ciò consente alla JVM di evitare l'apertura di tutti i file jar nei percorsi di classe di avvio e quando viene caricata una classe di applicazione Java.

Questo particolare miglioramento non dovrebbe avere alcun impatto sull'esecuzione di programmi, poiché le classi dal jar di sistema sarebbero già state caricate. Avrebbe solo effetto il primo tempo di avvio dell'applicazione.

+0

ProGuard modifica le classi dell'applicazione, che, AFAICT, non ottengono nulla da questo avvio JVM -time miglioramento delle prestazioni. Quindi, se questo è ciò a cui si riferiscono, sembra fasullo. Sembra che "deve" esserci qualche ottimizzazione del classloader relativa alle classi di applicazioni che può essere applicata solo ai file di classe che sono compilati per 6 o che sono stati elaborati da ProGuard. –

+0

@Raze, questo non ha nulla a che fare con l'ottimizzazione di cui si chiede la domanda. – Antimony

1

(rispondendo alla mia domanda)

ho trovato la maggior parte della risposta in questa sezione "What is preverification?" sul sito ProGuard:

Quando i file di classe di carico, il caricatore di classe esegue alcune sofisticate verifica del codice byte. Questa analisi assicura che il codice non possa accidentalmente o intenzionalmente uscire dalla sandbox della macchina virtuale . [...] Java 6 ha introdotto la verifica divisa. [...] Il compilatore Java 6 aggiunge le informazioni di preverificazione ai file di classe ([...] l'attributo StackMapTable), al fine di semplificare la fase di verifica effettiva per il caricatore di classi. I file di classe possono quindi essere caricati più velocemente e in un modo più efficiente in termini di memoria.

Questo non sembra rilevante per la concorrenza.

Quindi la domanda rimanente è: "È significativo?", che è in gran parte risposto "no" a:

Performance impact of Java class files generated with "-target 1.5" running on a 1.6 VM?