2015-09-11 15 views
5

Sono curioso di sapere come vengono gestiti i campi staticfinal da JVM. Ho visto una domanda simile here ma non è quello che sto cercando. Consideriamo ad esempio:finale statico rispetto ai campi non statici finali e ottimizzazione JVM

public class TestClassX { 
    public final int CODE_A = 132; 
    public final int CODE_B = 948; 
    public final int CODE_C = 288; 
    // some other code 
} 

public class TestClassY { 
    public static final int CODE_A = 132; 
    public static final int CODE_B = 948; 
    public static final int CODE_C = 288; 
    // some other code 
} 

In TestClassX campi, in quanto sono final e non possono essere modificati, hanno gli stessi valori in tutte le istanze della classe TestClassX. Naturalmente non posso scrivere TestClassX.CODE_A ma posso dire che questi valori sono in realtà comuni per tutte le istanze - sono sicuro che ogni istanza ha un campo CODE_A con il valore 132.

Nel TestClassY Posso usare la sintassi TestClassY.CODE_A, ma a prima vista è solo più semplice per uno sviluppatore che vede "Oh, quei valori sono comuni a tutte le istanze".

La mia domanda principale: Credo che JVM, in caso di TestClassX, non utilizza alcuna memoria aggiuntiva per final campi ogni volta che viene creata una nuova istanza. Lo fa? JVM fa qualche ottimizzazione in questo caso e che tipo di ottimizzazione è?

Extra domanda 1) Sono anche sicuro che mi manca qualcosa di molto importante qui che è la causa dei miei dubbi. Cos'è quello?

Extra domanda 2) Btw. Come posso vedere come appare il mio codice sorgente Java dopo l'ottimizzazione JVM (quindi posso usarlo in futuro;))? Qualche IDE supporta tale funzionalità? IntelliJ per esempio? Vorrei semplicemente vedere come JVM tratta il mio TestClassX e TestClassY.

+0

correlate - javac inlines sempre variabili di istanza costante, probabilmente un bug :) - https://groups.google.com/forum/#!topic/java-lang-fans/AyS3UqX4lj4 – ZhongYu

+0

2) ottimizzazioni del JVM aren fatto in un modo che si presta ad essere espresso come sorgente Java. I compilatori ottimizzano una rappresentazione interna di ciò che il codice * fa *.source-> source optimizer di solito esiste solo per le lingue che devono essere compilate ogni volta che vengono utilizzate (ad esempio javascript). Il tuo obiettivo attuale dovrebbe essere coperto osservando il codice byte Java o l'asm derivante dalla compilazione JIT per una CPU specifica. (O tradizionale compilazione anticipata per le implementazioni Java come gcj'.) –

risposta

6
  • I campi non statici sono sempre presenti nelle istanze. Non salvano la memoria.
  • In generale, JVM non ottimizza i campi non statici. Anche se sono definitivi, possono essere ancora impostati su un valore diverso mediante la riflessione o durante la deserializzazione.
  • Esiste un'opzione VM sperimentale -XX:+TrustFinalNonStaticFields (disattivata per impostazione predefinita) che indica a JVM di ottimizzare l'accesso a tali campi, ovvero trattarli come costanti ed eliminare i carichi di campo.
  • C'è un'opzione -XX:+PrintAssembly VM per eseguire il dump del codice compilato con JIT.
+0

Grazie per aver parlato di riflessione e deserializzazione . E per l'opzione TrustFinalNonStaticFields: non lo sapevo! ... ^ –

1

Per la prima parte della tua domanda, forse this answer può aiutarti.

Per la seconda parte è stato possibile vedere il gruppo generato (come indicato in this answer) aggiungendo il flag -XX:+PrintOptoAssembly quando si esegue/compila il codice.

Devo anche aggiungere che il codice assembly fornito non è il vero codice operativo generato da jvm, ma il codice deve essere eseguito sotto l'architettura effettiva .

Spero che questo aiuti!

+0

Mi dispiace di non averlo postato come commento, ma non ho abbastanza reputazione per farlo ... –

Problemi correlati