Flusso di caricamento della class per un programma semplice

Sto solo ora iniziando a imparare l’architettura interna di Java. Ho capito a grandi linee il concetto di caricamento di classi che carica le classi richieste quando jvm esecuzione, ClassNotFoundException viene lanciata quando una class non viene trovata e il caricatore di classi specifico carica le classi a cui fa riferimento la class.

Qualcuno può spiegare chiaramente il stream di caricamento della class, vale a dire la sequenza di caricamento della class di bootstrap e il caricamento della class definita dall’utente nel seguente codice Java di esempio.

 import java.io.File; public class Sample { public static void main(String[] args) { String fileName = "sample"; File file = new File(fileName); file.isFile(); } } 

Inoltre ho imparato da un materiale di riferimento che ” classloader mantiene gli spazi dei nomi delle classi che carica”. Per namespace, significa i nomi letterali della class? Inoltre, qualcuno può spiegare l’implicazione / vantaggio di ciò?

Esegui la tua class di Sample come segue

> java Sample

per poca magia, controlla l’output di -verbose:class opzione di -verbose:class e vedi tonnellate di linee seguenti ..

 [Opened C:\jdk1.6.0_14\jre\lib\rt.jar] [Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar] [Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar] [Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar] . . . . . . [Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar] [Loaded Sample from file:/D:/tmp/] [Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar] [Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar] 

\jre\lib\rt.jar visualizzato un gruppo di classi da \jre\lib\rt.jar caricate, molto prima che la class venga caricata dal caricatore della class Bootstrap (o Primordial). Questi sono i prerequisiti per l’esecuzione di qualsiasi programma Java quindi caricato da Bootstrap.

Un altro set di jar viene caricato dal loader della class Extension . In questo particolare esempio, non è stato necessario alcun tipo di class da lib \jre\lib\ext quindi non è stata caricata. Ma al caricatore della class Extension viene assegnato in modo specifico il compito di caricare le classi dall’estensione lib.

EDIT: Oltre alle classi java della piattaforma standard, Sun / Oracle fornisce anche un set di jar utilizzati per estendere l’API core della piattaforma . I vasi posizionati nella cartella lib di estensione vengono posizionati automaticamente nel classpath e quindi non sono necessari per essere inclusi in classpath in modo esplicito. Ecco un bell’articolo ufficiale sullo stesso argomento.

Infine, il Sample class viene caricato dal caricatore della class Application dopo che Bootstrap ed Extension hanno terminato il caricamento.

Gerarchia di Classloader

Ogni volta che viene avviata una nuova JVM, il classloader bootstrap è responsabile di caricare prima le classi chiave Java (dal pacchetto java.lang ) e altre classi di esecuzione. Il programma di caricamento di class bootstrap è padre di tutti gli altri programmi di caricamento classi. Di conseguenza, è l’unico senza genitore.

Poi arriva l’estensione classloader. Ha il bootloader del programma di caricamento come genitore ed è responsabile del caricamento delle classi da tutti i file .jar memorizzati nel percorso java.ext.dirs , disponibili indipendentemente dal percorso di class della JVM.

Il terzo e più importante classloader dal punto di vista dello sviluppatore è il classloader del classpath di sistema, che è un figlio immediato del classloader dell’estensione. Carica le classi dalle directory e dai file jar specificati dalla CLASSPATH ambiente CLASSPATH , java.class.path proprietà di sistema -classpath o -classpath riga di comando -classpath .

Gerarchia di Classloader

ClassLoader Namespace

In Java una class viene identificata in modo univoco utilizzando ClassLoader + Class poiché la stessa class può essere caricata da due diversi programmi di caricamento class.

 Class A loaded by ClassLoader A != Class A loaded by ClassLoader B 

Come è utile?

È utile per definire diverse politiche di protezione e accesso per diversi classloader. Prendi un esempio di applet che viene caricata utilizzando un diverso programma di caricamento classi, non vorrai che un’applicazione di terze parti acceda a tutte le tue risorse. Quindi per la sicurezza è importante mantenere spazi dei nomi diversi.

JVM gestisce un pool di runtime nell’area permgen dove vengono caricate le classi. Ogni volta che una class viene referenziata, il programma di caricamento classi trova la class nel percorso della class e la carica in questo pool. E questo non è specifico per classi definite dall’utente o classi fornite in JDK. Quando si fa riferimento a una class, questa viene caricata nella memoria.

Le classi caricate da ClassLoader vengono archiviate internamente nell’istanza ClassLoader

 // The classs loaded by this class loader. The only purpose of this table // is to keep the classs from being GC'ed until the loader is GC'ed. private final Vector> classs = new Vector<>(); 

Quando la class deve essere aggiunta alla memoria, viene chiamata la seguente funzione:

 // Invoked by the VM to record every loaded class with this loader. void addClass(Class c) { classs.addElement(c); } 

Trovato un diagramma utile su come funzionano i caricatori di class.

inserisci la descrizione dell'immagine qui

La Java Virtual Machine si avvia creando una class iniziale, che viene specificata in modo dipendente dall’implementazione, usando il caricatore della class bootstrap ( §5.3.1 ). La Java Virtual Machine collega quindi la class iniziale, la inizializza e le variabili di istanza statiche dichiarate al suo interno e infine richiama il metodo di class public void main (String []) . L’invocazione di questo metodo guida tutte le ulteriori esecuzioni. L’esecuzione delle istruzioni della Java Virtual Machine che costituiscono il metodo principale può causare il collegamento (e conseguentemente la creazione) di classi e interfacce aggiuntive, nonché l’invocazione di metodi aggiuntivi.

leggi questo link

Il processo di caricamento può essere visualizzato come interazione tra il sottosistema di Classloader e l’area di memoria di JVM.

Classloader funziona in tre passaggi generali 1.) Caricamento 2.) Collegamento e 3. Inizializzazione.

L’interazione di base tra Sottosistema Classloader e Area di memoria avviene durante il collegamento (a parte le altre interazioni!)

L’attività di collegamento è suddivisa in i.) Verifica ii.) Prepara e iii.) Risolvi. Verifica: è più per sicurezza, la compilazione valida è selezionata. Nel passaggio ii). Preparazione: la memoria variabile statica viene allocata e assegnata con valori predefiniti. E in

iii.) Risoluzione: i riferimenti simbolici vengono sostituiti con riferimenti originali dalla “Area metodo” che contiene dati di livello di class e variabili statiche.

JVM Arch