Clasificare și funcția classloaders

După cum știți, programele Java sunt traduse în bytecode executat de către o mașină virtuală Java (JVM) - un program care procesează un interpret de cod octet și instrucțiuni de transmitere. Este clar că, înainte de a interpreta bytecode, acesta trebuie să fie încărcate în memoria principală a unui calculator. Deci, cum este încărcată prima clasă?

Toate clasele în Java încărcate de încarcatoare de clasă. Inițial, programul creează 3 încărcător clasa de bază:

încărcător de bază (bootstrap)

Advanced Boot Loader (extensie)

un încărcător de boot (sistem / aplicație)

În plus față de încărcătoarelor clasă de bază, este posibil să se creeze personalizate incarcator de clasă. Pe acestea vor fi discutate mai târziu.

Incarcator folosit de clasă sunt ierarhice. Loader care încarcă clasele de sistem de bază, numit de bază (Bootstrap sau Primordial) încărcător de clasă. Adică, se încarcă pachetele JDK și clasele interioare Java. * (Rt.jar și i18n.jar). Este important să rețineți că încărcătorul de boot de bază este „Primordial sau rădăcină“ și o parte din JVM, ca urmare a care nu poate fi creat în cadrul codului de program.

Atunci de ce avem nevoie de alte alimentatoare, în cazul în care încărcătorul de bază atât de rău face treaba? De ce a fost necesar să se împartă procedura de clasa de încărcare în mai multe etape? Pentru a răspunde la această întrebare trebuie să ia în considerare alte încărcătoare de clasă, și interacțiunea lor.

Astfel, extensiile de incarcare - sarcini diverse pachete de expansiune, care sunt localizate în directorul / / Ext Lib sau alte descrise în java.ext.dirs parametrilor sistemului. Acest lucru vă permite să actualizați și să adăugați noi extensii fără a fi nevoie de a modifica setările utilizate de aplicații. Extensiile Downloader puse în aplicare de o clasă sun.misc.Launcher $ ExtClassLoader.

Și, în sfârșit, încărcătorul de boot - încarcă clase, calea la care este specificat în variabila de mediu CLASSPATH sau calea specificată în rândul de comandă de chei după -classpath sau -cp. Bootloader este implementat clasa sun.misc.Launcher $ AppClassLoader.

Principiul de funcționare al clasei încarcatoare

Fiecare încărcător de clasă (cu excepția Bootstrap) este încărcătorul-mamă, iar în cele mai multe cazuri, el solicită încărcătorul-mamă pentru a încărca clasa specificată, înainte de a încerca să-l descărcați singur.

Există, de asemenea, o modalitate evidentă de a iniția descărcarea clasei. Aparentă inițiere efectuată folosind ClassLoader.loadClass () sau Class.forName (). De exemplu, inițierea explicită este utilizată la încărcarea JDBC conducător auto: Class.forName ( „oracle.jdbc.driver.OracleDriver“);

Ierarhia de incarcatori de clasă, după cum urmează:

public class ClassLoadersTest

statice void main (String [] args) publice

Sistem. out. println (.. i getClass () getClassLoader ());

Call i.getClass (). GetClassLoader () returneaza null, ceea ce indică faptul că clasa a fost încărcată de încărcător este baza.

Să ne uităm la procesul de încărcare de clasă mai detaliat. Să presupunem că avem o clasă pe care o vom încărca (cum ar fi Integer). Procesul de descărcare este după cum urmează:

Sistem și downloader de rețea (sun.misc.Launcher $ AppClassLoader) verifică, dacă nu clasa a fost încărcată mai devreme. Dacă este deja încărcată, se returnează clasa cache. Dacă nu, delegații încărcător sistemul de căutare de clasă părinte clasa-încărcător.

Advanced Boot Loader (sun.misc.Launcher $ ExtClassLoader) efectuează aceeași procedură

În cele din urmă, încărcătorul de bază (bootstrap), încarcă clasa Integer pe cont propriu, deoarece nu are nici o clasă părinte.

Astfel, procesul de încărcare are o proprietate importantă, și anume delegare (figura 1). Acest lucru permite încărcător pentru a încărca clase, care este cel mai apropiat de bază în ierarhia de delegare. În consecință, clasele de căutare va avea loc în sursele, în ordinea de încredere, mai întâi în biblioteca de bază API, apoi folderul Extensii, apoi la classpath fișierele locale.

Cu alte cuvinte, dacă ați descărcat o terță parte din clasa de bibliotecă Integer și a arătat într-un mod variabil, ar încărcat încă original, Integer (număr întreg).

O altă caracteristică importantă - fiecare downloader are propriul spațiu de nume pentru clasele generate. Ie în cazul în care clasele sunt aceleași și sunt în același pachet, dar încărcate de diferite incarcator - acestea sunt diferite. Astfel, este posibil, de exemplu, pentru a crea două obiecte Singleton dacă încercați :)

Incarcator clasa personalizată

În Java, este posibil să se creeze personalizate incarcator de clasă. Acest lucru poate fi util atunci când nu există nici un posibil sau de dorit să se enumera toate bibliotecile utilizate atunci când programul începe în CLASSPATH. De exemplu, programul trebuie să fie capabil de a încărca dinamic plugin-uri. Sau capacitatea de încărcător standard nu este suficient pentru a descărca clasele necesare.

incarcator clasa proprii utilizate de toate serverele de aplicații și web-containere, și de înțeles - aplicații, dislocabile pe un server de aplicații care urmează să fie încărcate dinamic, se transferă în alt mod la variabila CLASSPATH bibliotecilor utilizate de aplicații, ea devine o sarcină non-triviale.

Pentru crearea personalizate classloaders clasa ClassLoader responsabil. Pentru a crea un încărcător de clasă personalizată, trebuie să fie moștenită de la ClassLoader de clasă.

Procesul de încărcare o clasă mai în detaliu

Procesul de încărcare a clasei este împărțit în trei părți:

Încărcare - În această fază, există o căutare și clasa de fizică pentru a descărca un fișier într-o anumită sursă (în funcție de dispozitivul de încărcare). Acest proces determină reprezentarea de bază a clasei în memorie. În acest stadiu, concepte, cum ar fi metode, domenii, etc. Nu este încă cunoscut.

Legarea - un proces care poate fi împărțit în trei părți:

Clasa de pregătire - în acest stadiu, structura de date de formare care hărți domenii, metode, și interfețe puse în aplicare, astfel cum sunt definite în clasă.

Soluționarea problemelor - să permită tuturor claselor care fac referire la clasa curentă.

Inițializarea - merge punerea în aplicare a initializatori statice definite în clasă. Astfel, câmpurile statice sunt inițializate cu valori implicite.

excepții

Atunci când se lucrează incarcator de clasă sunt cele mai frecvente următoarele excepții:

1. ClassNotFoundException. este aruncat atunci când o aplicație încearcă să se încarce o clasă prin numele său (String), prin mijloace cum ar fi:

Metoda forName din clasa de clasă.

Metoda findSystemClass în clasa ClassLoader.

Metoda loadClass în clasa ClassLoader.

Dar clasa cu același nume nu există.

2. NoClassDefFoundError. capturi în astfel de cazuri:

Când copierea de rezervă, directorul sau altă sursă de clase obligatorii nu a fost adăugat la sursele încărcătorului de clasă curent și strămoșii săi.

Loader strămoș nu a fost instalat corect.

Uneori, probleme cu o sarcină de clasă, manifestat nu numai la pornirea sistemului, dar în etapa de utilizare a clasei.

clase de descărcare

În cele mai multe cazuri, ciclul de viață al unei clase în mașina virtuală este similar cu ciclul de viață al obiectului. download-uri JVM, link-uri și inițializează clase, permițând ca programul să le folosească, și atunci când o aplicație descarcă în care nu mai sunt utilizate. Este important de remarcat faptul că descărcarea claselor nu funcționează în cazul în care clasa a fost încărcat încărcător Bootstrap.

clase de încărcare maximă, în ciuda faptului că acestea sunt cu drepturi depline Java obiecte sunt stocate într-o zonă specială de memorie de sistem numit generare permament (prescurtat, PermGen) și gestionat de către colector de gunoi.

Descarcarea clase este o parte importantă a mecanismului de JVM ca un program Java se poate extinde în mod dinamic în timpul descărcării clase personalizate și, astfel, ocupă mult spațiu în memoria RAM. Țineți clase în memorie, care nu vor mai fi folosite, nu există nici un punct.

Specifice pentru clasa politică de descărcare depinde de punerea în aplicare a JVM mașinii virtuale.

concluzie

Astfel, suntem un pic mai aproape de intelegerea procesului de încărcare clasa JVM. au fost considerate tipuri de downloader, ierarhie, faza lor de clasa de încărcare și situații excepționale care pot apărea în acest proces.