2012-04-18 23 views
49

Attualmente sto cercando di approfondire le specifiche della Java Virtual Machine. Ho letto Inside the JVM book online e c'è un'astrazione confusa che non riesco a capire: Constant Pool. ecco l'estratto dal libro:Qual è lo scopo del pool di costanti Java?

Per ogni tipo caricato, una macchina virtuale Java deve memorizzare un pool costante. Un pool costante è un insieme ordinato di costanti utilizzate dal tipo, inclusi valori letterali (stringhe, numeri interi e costanti floating point) e riferimenti simbolici a tipi, campi e metodi. Le voci nel pool costante sono referenziate dall'indice, proprio come gli elementi di un array. Perché contiene riferimenti simbolici a tutti i tipi, i campi ei metodi utilizzati da un tipo, la piscina costante svolge un ruolo centrale nel collegamento dinamico dei programmi Java

Ho diverse domande circa il sopra e CP in generale:

  1. Il CP si trova nel file .class per ciascun tipo?
  2. Cosa significa l'autore per "riferimento simbolico"?
  3. Qual è lo scopo del Pool costante, in inglese semplice?

risposta

51

Penso che capire come si costruisce il telaio utilizzando un diagramma potrebbe essere d'aiuto.

enter image description here

Il telaio è dove gli operandi (funzionamento) risiedono e che è dove si verifica il collegamento dinamico. È un modo stenografico, per così dire, usando il pool costante per tenere traccia della classe e dei suoi membri.

Ogni frame contiene un riferimento al pool di costanti di runtime. Il riferimento punta al pool costante per la classe del metodo in esecuzione per quel frame. Questo riferimento aiuta a supportare il collegamento dinamico.

Il codice C/C++ viene in genere compilato in un file oggetto, quindi più file oggetto sono collegati insieme per produrre un artefatto utilizzabile come un eseguibile o una DLL. Durante la fase di collegamento i riferimenti simbolici in ogni file oggetto vengono sostituiti con un indirizzo di memoria reale relativo all'eseguibile finale. In Java questa fase di collegamento viene eseguita dinamicamente in fase di runtime.

Quando un file Java viene compilato, tutti i riferimenti a variabili e metodi sono memorizzati nel pool costante della classe come riferimento simbolico. Un riferimento simbolico è un riferimento logico e non un riferimento che indica effettivamente una posizione di memoria fisica.

Ecco un collegamento a James Blooms JVM Internals per ulteriori dettagli.

+0

"Quando una classe Java è compilata ..."? Un file .class non è già un codice Java compilato? –

+1

Sì, un file .java diventa un file .class quando viene compilato. –

+0

il link è rotto –

6

Qual è lo scopo del Pool costante, in inglese semplice?

Il CP è un'area di memoria valori costanti molto univoci vengono memorizzati per ridurre la ridondanza:

System.err.println("Hello"); 
System.out.println("Hello"); 

Nel CP v'è un solo stringa oggetto "Ciao" e il compilatore sostituti in entrambe le linee a stesso riferimento. Il tuo file .class contiene solo una stringa Hello. (Lo stesso per altri tipi).

CP si trova nel file .Class per ciascun tipo?

Sì, guarda qui: http://en.wikipedia.org/wiki/Java_class_file

+0

Vuoi espandere un po 'di più sui collegamenti simbolici, forse? Penso che queste siano la parte più importante di CP – Bober02

63

piscina Constant è una parte del .class file (e la sua rappresentazione in memoria) che contiene le costanti necessari per eseguire il codice di quella classe.

Queste costanti includono valori letterali specificati dal programmatore e riferimenti simbolici generati dal compilatore. I riferimenti simbolici sono fondamentalmente nomi di classi, metodi e campi a cui si fa riferimento dal codice. Questi riferimenti vengono utilizzati da JVM per collegare il codice ad altre classi da cui dipende.

Ad esempio, il seguente codice

System.out.println("Hello, world!"); 

produce il seguente codice byte (javap uscita)

0: getstatic  #2; //Field java/lang/System.out:Ljava/io/PrintStream;    
3: ldc  #3; //String Hello, world!             
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 

#n qui sono riferimenti alla piscina costante. #2 è un riferimento simbolico al campo System.out, #3 è una stringa Hello, world! e #4 è un riferimento simbolico al metodo PrintStream.println(String).

Come si può vedere, i riferimenti simbolici non sono solo i nomi - ad esempio, simbolico riferimento al metodo contiene anche informazioni sui suoi parametri (Ljava/lang/String;) e tipo di ritorno (V significa void).

È possibile controllare il pool costante di una classe eseguendo javap -verbose per quella classe.

+0

@ axtavt- wow! bella spiegazione sembra un piccolo refuso vicino a "# 3 è un riferimento simbolico a PrintStream .." non dovrebbe essere # 4 –

+0

@mashit: Sì, corretto. – axtavt

+0

Ma cosa significa "L" in "Ljava/lang/String;" ? – JackWM

1

Let dare Esempio primo a capire che cosa String piscina costante significa

public class StringConstantPool { 
     public static void main(String[] args) { 
      String s = "prasad"; 
      String s2 = "prasad"; 

      System.out.println(s.equals(s2)); 
      System.out.println(s == s2); 
     } 
    } 

l'uscita sarà

true 

true 

cosa succede qui, passo dopo passo

1- Il la classe viene caricata quando viene richiamata la JVM.

2- JVM cercherà tutti i valori letterali stringa nel programma.

3- primo luogo, essa trova il variabile s che si riferisce al letterale “Prasad” e sarà creato nella memoria

4- Un riferimento per la letterale “prasad” verrà inserito nella memoria del pool costante di stringhe.

5- quindi lo rileva un'altra s2 variabile che si riferisce alla stessa stringa letterale “Prasad”.

Ora che JVM ha già trovato una stringa letterale “prasad”, entrambe le variabili s e s2 wil riferiscono allo stesso oggetto cioè “Prasad”.

enter image description here

Spero che questo sia utile

saperne di più http://www.journaldev.com/797/what-is-java-string-pool

+2

Non esiste il "pool costante di stringhe". Esiste un "pool costante" che esiste in ogni file di classe e esiste un "pool di stringhe" di stringhe internate che esistono per JVM. – Keenle

+0

sì, volevo dire String pool, Grazie per il commento –