Класификация и функционални classloaders

Както знаете, Java програми са преведени на байткод изпълнен от виртуална машина Java (JVM) - програма, която обработва един байт код преводач и предаване на инструкции. Ясно е, че преди да се тълкува байткод, тя трябва да бъде зареден в основната памет на компютъра. И така, как зареден е първи клас?

Всички класове в Java се зареждат от клас товарачи. Първоначално програмата създава 3 клас основен товарач:

основния товарач (фърмуера)

Advanced Boot Loader (разширение)

на програмата за начално зареждане (система / приложение)

В допълнение към основните товарачи класа, че е възможно да се създаде клас товарачи поръчка. На тях ще бъдат обсъдени по-късно.

Клас товарачи са йерархични. Loader, който зарежда основните класове система, наречена база (фърмуера или Primordial) клас товарач. Това означава, че тя зарежда пакетите JDK и Java вътрешни класове. * (Rt.jar и i18n.jar). Важно е да се отбележи, че основната зареждане на ОС е "Първичен или корен" и част от JVM, в резултат на което той не може да бъде създаден в рамките на програмния код.

Тогава защо се нуждаем от другите хранилки, ако е толкова лошо базовата товарач си върши работата? Защо е било необходимо да се раздели процедура клас натоварване на няколко етапа? За да отговорим на този въпрос, трябва да се разглеждат другите товарачи клас, както и тяхното взаимодействие.

По този начин, разширения товарач - натоварвания различни разширяване опаковки, които се намират в директорията / Lib / вътр указател или друг описан в java.ext.dirs за системни параметри. Това ви позволява да се актуализира и се добавят нови разширения без да е необходимо да промените настройките, използвани от приложения. разширения Downloader изпълнявани от един клас sun.misc.Launcher $ ExtClassLoader.

И накрая, зареждане на ОС - товари класове, пътят към който е посочен в променливата CLASSPATH среда или по пътя, посочен в командния ред на клавишите след -classpath или -СР. зареждането на ОС се реализира клас sun.misc.Launcher $ AppClassLoader.

Операционната принципа на класа товарачи

Всеки клас товарач (с изключение на фърмуера) е майка на ОС, а в повечето случаи той моли майка товарач за зареждане на съответния клас, преди да се опитате да го изтеглите себе си.

Има и един очевиден начин за започване на изтеглянето на класа. Видимият започването провежда при използване ClassLoader.loadClass () или Class.forName (). Например изрично започване се използва при зареждане на JDBC драйвер: Class.forName ( "oracle.jdbc.driver.OracleDriver");

Йерархията на класа товарачи, както следва:

обществени клас ClassLoadersTest

публично статично невалидни основни (String [] опцията)

System. навън. println (.. аз getClass () getClassLoader ());

Повикване i.getClass (). GetClassLoader () връща нула, което показва, че този клас се зарежда от товарач е основата.

Нека да разгледаме процеса на товарене на класовете по-подробно. Да предположим, че имаме класа, че ние ще се зареди (като цяло число). Процесът на изтегляне е, както следва:

Система и мрежа изтегляне (sun.misc.Launcher $ AppClassLoader) проверява, а не дали този клас се зарежда по-рано. Ако тя вече е зареден, той се връща в класа на кеша. Ако не, система за челни товарачи делегати за търсене клас родител клас-товарач.

Advanced Boot Loader (sun.misc.Launcher $ ExtClassLoader) изпълнява същата процедура

Базовата товарач (работят поетапно), зарежда клас Integer сами по себе си, защото няма родител клас.

По този начин, процесът на зареждане има важно свойство, а именно делегация (Фигура 1). Това позволява на зареждане, за да заредите класове, което е най-близо до базата в йерархията на делегация. В резултат на това търсене класове ще се проведе в източниците по реда на тяхното доверие, за първи път в библиотеката ядрото API, а след това папката Extensions, а след това да CLASSPATH на локални файлове.

С други думи, ако сте изтеглили от трета страна библиотека Integer клас А и го насочи в променлива начин, той все пак ще зарежда оригинален Цяло число (цяло число).

Друга важна особеност - всеки изтегляне разполага със собствен пространство от имена за генерираните класове. Т.е. ако класовете са едни и същи и са в една и съща опаковка, но натоварени с различни товарачи - те са различни. Така, че е възможно например да се създаде два обекта Сингълтън, ако се опитате :)

Клас по поръчка товарачи

В Java, то е възможно да се създаде клас товарачи поръчка. Това може да бъде полезно, когато няма или те са недостатъчни, за да се изброят всички използвани библиотеки, когато програмата започва в CLASSPATH. Например, програмата трябва да може да се зареди динамично плъгини. Или стандартен капацитет товарач, не е достатъчно, за да изтеглите редовните лекции.

Собствени товарачи класа, използвани от всички сървъри за приложения и уеб-контейнери и това е разбираемо - приложения, за развръщане на сървър на приложения, за да се заредят динамично, в противен случай прехвърли на променливата CLASSPATH от библиотеките, използвани от приложения, тя се превръща в не е тривиална задача.

За създаването на потребителски classloaders отговорен ClassLoader клас. За да създадете потребителски клас товарач, трябва да бъде наследен от ClassLoader клас.

Процесът на зареждане на класа по-подробно

Процесът на зареждане на класа е разделена на три части:

Товаро - В тази фаза, има търсене и физическа клас да изтеглите файл в определен източник (в зависимост от зареждането на системата). Този процес определя основния представяне на класа в паметта. На този етап, понятия като методи, полета и т.н. Все още не е известна.

Свързване - процес, който може да бъде разделен на три части:

подготовка класа - на този етап структурата на обучение данни, който съпоставя полета, методи и интерфейси изпълнени, както е определено в този клас.

Решаването - да разреши всички класове, които се обръщат текущия клас.

Инициализация - текущото изпълнение на статични инициализатори дефинирани в класа. По този начин, статични полета са със стойности по подразбиране.

изключения

При работа клас товарачи са най-често срещаните следните изключения:

1. ClassNotFoundException. се хвърля, когато някое приложение се опитва да се зареди един клас по неговото име (String) чрез методи като:

метод forName в клас клас.

метод findSystemClass в клас ClassLoader.

метод loadClass в клас ClassLoader.

Но този клас със същото име не съществува.

2. NoClassDefFoundError. улова си в такива случаи:

Когато архивирате, директорията или друг източник на изискваните класове не е добавен към източниците на текущия клас товарач и неговите предци.

Loader предшественик не е инсталиран правилно.

Понякога проблеми с натоварването клас, проявяват не само по време на зареждане, но на етапа на използване на класа.

класове разтоварване

В повечето случаи, жизнения цикъл на един клас в виртуалната машина е подобна на жизнения цикъл на обект. JVM сваляния, връзки и инициализира класове, което позволява на програмата да ги използват, и разтоварва, когато приложение вече не се използва. Важно е да се отбележи, че разтоварването на класове не работи, ако класът е зареден за първоначално зареждане на ОС.

Заредени класове, независимо от факта, че те са пълноправни Java-обекти се съхраняват в специална зона системна памет, наречена permament поколение (съкращение, PermGen) и се управлява от боклукчията.

Разтоварни класове е важна част от JVM на механизъм като програма на Java може динамично да се разшири по време на сваляне на потребителски класове и по този начин заемат много място в RAM. Задръжте класове в паметта, която няма да се използва повече, няма смисъл.

Специфична политика клас разтоварване зависи от изпълнението на JVM на виртуалната машина.

заключение

По този начин, ние сме малко по-близо до разбирането на процеса на зареждане клас на JVM. Бяха разгледани видове програми за изтегляне, тяхната йерархия, клас натоварване фаза и извънредни ситуации, които могат да възникнат в процеса.