In che modo java risolve i nomi delle classi in molti barattoli?

7

Recentemente ho trovato uno dei miei progetti Maven con oltre 100 dipendenze jar. FWIK un archivio zip non ha indice, quindi dovrebbe eseguire la scansione dell'intero zip per determinare se contiene un percorso specifico.

Ma ho trovato che Java risolve i nomi delle classi su così tanti vasi piuttosto velocemente, perché?

    
posta Xiè Jìléi 20.05.2011 - 02:11
fonte

2 risposte

1

Il formato ZIP (di cui JAR è un'estensione) consiste in un insieme di sezioni compresse e una sezione di indice alla fine. La sezione indice contiene i nomi di file completi (beh, completi relativi alla radice dello ZIP) dei file contenuti nello ZIP, insieme ad altri metadati (ad esempio, dove sono i dati compressi) il che significa che trovare ciò che è in un ZIP è in realtà un'operazione molto veloce. Poiché una classe esegue il mapping su un singolo file .class in modo triviale, scoprire se un JAR lo contiene è di per sé molto veloce anche prima di considerare qualsiasi caching.

Tutto ciò deriva dall'uso originale del formato ZIP come formato di archivio compresso multi-disco; quando si espande, si dovrebbe decomprimere inserendo l'ultimo disco di un set (in modo che l'indice possa essere letto) prima di iniziare a gestire i dati compressi dall'inizio del primo disco. Ovviamente, se hai finito i dischi prima di aver finito di scrivere l'archivio, eri completamente SOL ...

    
risposta data 20.05.2011 - 14:37
fonte
6

Non esplora ogni riferimento finché non deve

In base alla specifica JVM il caricatore bootstrap è specificato per funzionare come segue:

5.3.1 Loading Using the Bootstrap Class Loader The following steps are used to load and thereby create the nonarray class or interface C denoted by N using the bootstrap class loader.

First, the Java virtual machine determines whether the bootstrap class loader has already been recorded as an initiating loader of a class or interface denoted by N. If so, this class or interface is C, and no class creation is necessary.

Otherwise, the Java virtual machine performs one of the following two operations in order to load C:

1: The Java virtual machine searches for a purported representation of C in a platform-dependent manner. Note that there is no guarantee that a purported representation found is valid or is a representation of C.

Typically, a class or interface will be represented using a file in a hierarchical file system. The name of the class or interface will usually be encoded in the pathname of the file.

This phase of loading must detect the following error:

  • If no purported representation of C is found, loading throws an instance of NoClassDefFoundError or an instance of one of its subclasses.

Then the Java virtual machine attempts to derive a class denoted by N using the bootstrap class loader from the purported representation using the algorithm found in Section 5.3.5. That class is C.

2: The bootstrap class loader can delegate the loading of C to some user-defined class loader L by passing N to an invocation of a loadClass method on L. The result of the invocation is C. The Java virtual machine then records that the bootstrap loader is an initiating loader of C (§5.3.4).

Notare l'uso della modalità dipendente dalla piattaforma. Ciò significa che quando si cerca una particolare istanza di una classe, la JVM deve esplorare un file system di qualche tipo. Nel caso della tua domanda è un mucchio di JAR.

Mentre cerca nel classpath, la JVM rende il proprio indice interno (probabilmente una mappa efficiente) basato sul nome JAR e sui percorsi che ha incontrato durante il processo di collegamento dinamico. Questo indice cresce man mano che vengono esplorati più JAR per risolvere tutti i riferimenti, ma potrebbe non includere tutti i JAR a meno che non esplorarli causino un ClassNotFoundException .

Questo processo di caricamento è aiutato dal fatto che la specifica del file JAR fornisce una funzione per /META-INF/INDEX.LIST che funge da indice attendibile delle definizioni di classe all'interno del JAR.

Un interessante effetto collaterale di questo processo è che le definizioni di classi duplicate con lo stesso nome e pacchetto ma le diverse firme di metodo non saranno necessariamente rilevate fino a quando l'esecuzione non avrà luogo ( NoSuchMethodException ecc.)

    
risposta data 20.05.2011 - 10:50
fonte

Leggi altre domande sui tag