¿Cómo java resuelve los nombres de clase en muchos tarros?

7

Recientemente encontré que uno de mis proyectos de Maven tiene más de 100 dependencias de archivos. FWIK un archivo zip no tiene ningún índice, por lo que debe escanear todo el archivo zip para determinar si contiene una ruta específica.

Pero encontré que los nombres de clase de resolución de Java contra tantos frascos son bastante rápidos, ¿por qué?

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

2 respuestas

1

El formato ZIP (del cual JAR es una extensión) consiste en un conjunto de secciones comprimidas y una sección de índice al final. La sección de índice contiene los nombres de archivo completos (bueno, completo en relación con la raíz del ZIP) de los archivos contenidos en el ZIP, junto con otros metadatos (por ejemplo, dónde están los datos comprimidos), lo que significa que encontrar lo que hay en un ZIP es en realidad una operación muy rápida. Dado que una clase se asigna a un solo archivo .class de manera trivial, encontrar si un JAR lo contiene es muy rápido incluso antes de considerar cualquier almacenamiento en caché.

Todo esto se deriva del uso del original del formato ZIP como un formato de archivo comprimido multidisco; al expandir, tendría que descomprimirlo insertando el último disco de un conjunto (para que se pueda leer el índice) antes de comenzar a tratar los datos comprimidos desde el principio del primer disco. Por supuesto, si se quedaron sin discos antes de terminar de escribir el archivo, estaba completamente SOL ...

    
respondido por el Donal Fellows 20.05.2011 - 14:37
6

No explora todas las referencias hasta que tenga que hacerlo

De acuerdo con la especificación de JVM el cargador de arranque es Especificado para trabajar de la siguiente manera:

  

5.3.1 Carga utilizando el cargador de clases de Bootstrap Los siguientes pasos son   utilizado para cargar y crear así la   clase o interfaz no ordenada C denotada   por N usando el cargador de clases bootstrap.

     

Primero, la máquina virtual de Java   determina si la clase bootstrap   cargador ya se ha registrado como una   iniciando el cargador de una clase o   interfaz denotada por N. Si es así, este   clase o interfaz es C, y no clase   la creación es necesaria.

     

De lo contrario, la máquina virtual de Java   realiza uno de los dos siguientes   Operaciones para cargar C:

     

1: la máquina virtual Java busca un supuesto   representación de C en una   De manera dependiente de la plataforma. Tenga en cuenta que   no hay garantía de que un supuesto   La representación encontrada es válida o es una   representación de C.

     

Por lo general, una clase o interfaz se representará usando un archivo en una   Sistema de archivos jerárquico. El nombre de   la clase o interfaz usualmente será   codificado en la ruta del archivo.

     

Esta fase de carga debe detectar el siguiente error:

     
  • Si no se encuentra una representación de C, carga   lanza una instancia de   NoClassDefFoundError o una instancia de   Una de sus subclases.
  •   

Luego, la máquina virtual Java intenta derivar una clase indicada por   N usando el cargador de clases bootstrap   de la supuesta representación   usando el algoritmo encontrado en la Sección   5.3.5. Esa clase es C.

     

2: el cargador de clases bootstrap puede delegar la carga de C a algunos   cargador de clases definido por el usuario L por pasar   N a una invocación de un loadClass   método en L. El resultado de la   La invocación es C. El Java virtual.   máquina entonces registra que la   bootstrap loader es un iniciador   cargador de C (§5.3.4).

Tenga en cuenta el uso de manera dependiente de la plataforma. Esto significa que cuando se busca una instancia particular de una clase, se requiere que la JVM explore un sistema de archivos de algún tipo. En el caso de su aplicación es un montón de JARs.

A medida que busca a través de la ruta de clase, la JVM crea su propio índice interno (probablemente un Mapa eficiente) basado en el nombre de JAR y las rutas que ha encontrado durante el proceso de vinculación dinámica. Este índice crece a medida que se exploran más JAR para resolver todas las referencias, pero puede no incluir todos los JAR a menos que no explorarlos causaría un ClassNotFoundException .

Este proceso de carga se ve facilitado por el hecho de que la especificación del archivo JAR proporciona una facilidad para /META-INF/INDEX.LIST que actúa como un índice confiable de definiciones de clase dentro del JAR.

Un efecto secundario interesante de este proceso es que las definiciones de clase duplicadas con el mismo nombre y paquete pero diferentes firmas de métodos no se detectarán necesariamente hasta que se lleve a cabo la ejecución ( NoSuchMethodException etc.)

    
respondido por el Gary Rowe 20.05.2011 - 10:50

Lea otras preguntas en las etiquetas