Донецкий техникум промышленной автоматики

Технологія Java, стиль IBM: Класи загального користування

  1. Серія контенту:
  2. Цей контент є частиною серії: Технологія Java, стиль IBM
  3. Як воно працює
  4. Активація загального користування класів
  5. кеш класів
  6. Як кешуються класи?
  7. Які частини класу кешуються?
  8. Що відбувається, якщо клас змінюється в файлової системі?
  9. Утиліти класів загального користування
  10. Лістинг 1. Створення двох кешей
  11. Лістинг 2. Лістинг всіх кешей
  12. Лістинг 3. Сумарна статистика для кеша
  13. Лістинг 4. Лістинг повного вмісту кеша
  14. Лістинг 5. Знищення кеша
  15. Лістинг 6. Знищення кешей, які не були використані протягом тижня
  16. вербалізувати опції
  17. Лістинг 7. Отримання інформації про статус JVM
  18. Модифікація середовища виконання байт-коду
  19. потенційні небезпеки
  20. Використання інтерфейсу Помічника API
  21. Інтерфейс Помічника API: Короткий виклад
  22. Використання SharedClassHelperFactory
  23. Використання SharedClassHelpers
  24. інші випадки
  25. Безпека
  26. Утилізація пам'яті і синхронне компіляція
  27. Межі розмірів кешу
  28. приклад
  29. Якість завантаження класів
  30. Лістинг 10. Розігрів кеша системного диска
  31. Малюнок 3. Результат не розігрітого кеша
  32. Малюнок 4. Результати розігрітого кеша
  33. Простір віртуальної пам'яті
  34. Малюнок 5. П'ять демо без поділу класів
  35. Висновок
  36. Ресурси для скачування

Технологія Java, стиль IBM

Властивість поділу класів допомагає зменшити займане місце в пам'яті і поліпшити початковий запуск програми

Серія контенту:

Цей контент є частиною # з серії # статей: Технологія Java, стиль IBM

https://www.ibm.com/developerworks/ru/views/global/libraryview.jsp?series_title_by=Технология+java,+стиль+ibm

Слідкуйте за виходом нових статей цієї серії.

Цей контент є частиною серії: Технологія Java, стиль IBM

Слідкуйте за виходом нових статей цієї серії.

Принцип створення класів загального користування між процесами віртуальної машини Java (JVM) вже не є новим. Наприклад, властивість CDS, надане фірмою Sun пише системні класи в файл тільки для читання, який має схему розподілу пам'яті в JVM. У властивості, зване Shiraz, в IBM z / OS®1.4.2 JVM, використовувала провідну JVM, щоб заповнити кеш класів, який потім був розділений підлеглими JVM.

Розроблена IBM версія 5.0 JVM заснована на концепції, що стоїть на сходинку вище, яка дозволяє всім класам системи і додатки зберігатися в постійному динамічному кеші класів загального користування. Дана властивість Розділених Класів підтримується на всіх платформах, розроблених IBM, в яких є JVM. Це властивість підтримує навіть впроваджену модифікацію середу виконання байт-кодів, яка розглядається в даній статті далі .

Властивість розділених класів було розроблено з нуля, в якості опції, яку ви можете просто включити і більше не думати про неї, хоча воно надає дуже потужні засоби для зменшення займаного місця в віртуальної пам'яті і прискорення початкове завантаження JVM. З цієї причини, це властивість найкраще підходить в умовах, коли більше однієї JVM виконують один і той же код або коли JVM постійно перезавантажується.

На додаток до підтримки класів загального користування середовищем виконання в JVM і підтримки її завантажувачами класів, також надається загальнодоступний інтерфейс Помічника API для впровадження підтримки класів загального користування в будь-завантажувачі класів, який розглядається в даній статті Детальніше .

Як воно працює

Давайте почнемо з вивчення технічних деталей того, як працює властивість Підрозділи Класів.

Активація загального користування класів

випуск Технологія Java, стиль IBM охоплює останні версії платформи Java, розробленої IBM. ви дізнаєтеся про те, як IBM реалізувала нові можливості, що входять до складу версії 5.0 Java платформи. А також ви дізнаєтеся про те, як використовувати деякі цінні доповнення, реалізовані в нових випусках від IBM.

Ви можете зв'язатися безпосередньо з авторами, надіславши їм свої коментарі або питання з приводу статей. Написати коментар на весь випуск Ви можете зв'язатися з провідним випуску Крісом Бейлі . Більш детально на теми, що розглядаються в цьому випуску, а також завантажити останні релізи від IBM, див. Розділ ресурси .

Ви активуєте класи загального користування за допомогою додавання -Xshareclasses [: name = <cachename>] в існуючу командний рядок коду на мові Java. Коли запускається JVM, вона шукає кеш класів, заданого імені (якщо ім'я не задано, вона вибирає стандартне ім'я), і вона або підключається до існуючого кешу або створює новий, якщо це потрібно.

Ви задаєте розмір кешу, використовуючи параметр -Xscmx <size> [k | m | g]. Цей параметр застосовується, тільки якщо JVM створила новий кеш. Якщо ця опція опущена, вибирається стандартне значення, в залежності від платформи (зазвичай 16MБ). Зауважимо, що існують настройки операційної системи, які можуть обмежувати кількість розділеної пам'яті, виділеної на розподіл - наприклад, SHMMAX в Linux зазвичай встановлений в розмірі близько 20MБ. Подробиці цих налаштувань ви можете знайти в розділі про Розділених Класу, відповідного користувальницького довідника (див. Розділ ресурси для посилання).

кеш класів

Кеш класів - це область виділеної пам'яті фіксованого розміру, який залишається незмінним протягом усього циклу JVM, що використовує його. В системі може існувати будь-яке число виділених кешей класів, залежно від налаштувань операційної системи або її обмежень. Однак, одна окрема JVM може лише приєднуватися до одного кешу протягом свого циклу.

Жодна JVM привласнює собі кеш, і не існує таких понять, як провідна або підпорядкована JVM. Навпаки, будь-яке число віртуальних машин Java можуть паралельно і читати, і писати в кеш. Кеш видаляє або коли його явно знищують за допомогою утиліти JVM, або коли перезапускається операційна система (кеш не може продовжувати працювати після перезапуску операційної системи). Кеш не може рости в розмірах і, коли він заповнюється, JVM може все одно завантажувати класи з нього, але не може додавати інші класи. Існує набір утиліт JVM для управління діючими кешами, про який більш детально йдеться в розділі, під назвою " Утиліти поділюваних класів ".

Як кешуються класи?

Коли JVM завантажує будь-якої клас, вона, спершу, дізнається, чи існує вже необхідний їй клас в кеші. Якщо він є в наявності, то віртуальна машина завантажує його з кешу. Інакше, вона завантажує клас з файлової системи і записує його в кеш в якості частини виклику defineClass (). Отже, нерозділена JVM має наступний порядок завантаження класів:

  1. Кеш завантаження класів
  2. Батьківський
  3. файлова система

Коли як в JVM, запускається з Розділенням Класів, використовується наступний порядок:

  1. Кеш завантаження класів
  2. Батьківський
  3. виділений кеш
  4. файлова система

Класи зчитуються і записуються в кеш за допомогою загальнодоступного інтерфейсу Помічника API, який включений в розробленому IBM java.net.URLClassLoader. Отже, будь-який завантажувач класів, який розширює java.net.URLClassLoader отримує підтримку класів загального користування безкоштовно.

Які частини класу кешуються?

Всередині віртуальної машини, розробленої IBM, класи Java діляться на дві частини: частина тільки для читання, звана ROMClass, яка містить всі постійні дані класу, і частина RAMClass, яка містить непостійні дані, такі як статичні змінні класу. RAMClass вказує на дані в своєму ROMClass, але обидві ці частини абсолютно роздільні, що означає, що вони досить безпечні для ROMClass, який розділяти між віртуальними машинами Java і навіть між класами RAMClasses в одній і тій же JVM.

У разі, коли класи нероздільний, JVM завантажує клас, вона створює ROMClass і RAMClass окремо і зберігає їх у своїй локальній пам'яті обробки. У разі, коли класи розділені, якщо JVM знаходить ROMClass в кеші класу, їй тільки треба створити RAMClass в своїй локальній пам'яті. Потім RAMClass адресує виділений ROMClass.

У зв'язку з тим, що велика частина даних класу зберігається в ROMClass, це там, де відбувається збереження віртуальної пам'яті. (Глава " Відбиток віртуальної пам'яті "Розглядає це питання більш детально.) Час запуску JVM також прискорюється в значній мірі з заповненим кешем, тому що частина роботи по визначенню кожного кешованого класу вже була проведена, і класи завантажуються з пам'яті, а не з файлової системи. Витрати часу запуску для заповнення нового кеша (про який я буду говорити далі в даній статті ) Не значні, так як кожен клас необхідно перемістити в кеш, як тільки він визначений.

Що відбувається, якщо клас змінюється в файлової системі?

У зв'язку з тим, що кеш може продовжувати діяти невизначено довго, відбуваються оновлення файлової системи, які оголошують недійсними класи в кеші. Внаслідок цього в відповідальність коду кеша входить гарантія того, щоб завантажувач класів зробив запит на клас загального користування, і потім щоб повертається клас був завжди точно таким класом, який міг бути завантажений з файлової системи. Очевидно, це відбувається тоді, коли класи завантажуються, і таким чином, користувач може змінювати і оновлювати стільки класів, скільки хоче під час дії кешу класів загального користування, знаючи при цьому, що спочатку правильні класи завжди будуть завантажуватися.

Уявіть клас C1, який завантажується Віртуальної Машиною Java (JVM) в кеш. Потім, коли JVM вимикається, клас C1 змінюється і перекомпілюється. Коли JVM включається заново, їй зовсім необов'язково завантажувати кешовану версію класу C1.

Таким же чином, уявіть JVM, яка запускається з наступним шляхом класу: /mystuff:/mystuff/myClasses.jar. Вона завантажує клас C2 з файлу myClasses.jar в кеш. Потім додається інший клас C2.class в / myStuff і інша JVM починає запускати те ж саме додаток. Буде невірно для JVM завантажувати кешовану версію класу C2.

JVM визначає поновлення файлової системи тим, що вона зберігає значення міток часу в кеші і порівнює кешированниє значення з дійсними значеннями при кожному завантаженні класів. Якщо вона визначає, що файл JAR був оновлений, вона зовсім не знає, які класи були змінені, тому всі класи, завантажені з файлу JAR, що знаходиться в кеші, моментально позначаються, як застарілі і не можуть більше бути скачаними з кешу. Коли завантажуються класи з файлу JAR даної файлової системи і знову додаються в кеш, повністю додаються лише ті класи, які дійсно були змінені. Інші ж незмінені класи практично не позначаються, як застарілі.

Класи прати з кешу неможливо, але, тим не менш, JVM робить спроби ефективно використовувати наявне у неї простір. Наприклад, один і той же клас ніколи не додається двічі, навіть якщо він завантажується з дуже різних джерел. Таким чином, якщо один і той же клас C3 завантажується з /A.jar, /B.jar і /C.jar трьома різними віртуальними машинами Java, дані класу додається лише один раз, але існує три шматочки метаданих, що описують ці три джерела, з яких клас був завантажений.

Утиліти класів загального користування

Існує набір утиліт, які можна використовувати при управлінні активними кешами, кожен з яких є подопціей -Xshareclasses. (Ви можете отримати повний список всіх дійсних подопцій -Xshareclasses, набравши java -Xshareclasses: help.)

Зауважимо, що жодна з утиліт (за винятком expire) насправді не запускає JVM, і тому вони виробляють запитувана дія і йдуть без запуску класу. Також відзначимо, що повідомлення Could not create the Java virtual machine (не може створити JVM) виводиться за допомогою Java launcher кожної з утиліт, тому що JVM не запущено. Це не є помилкою.

Давайте розберемо кілька прикладів, щоб продемонструвати використання цих опцій. По-перше, давайте створимо два кеша, запустивши клас HelloWorld з різними іменами кешей, як показано в лістингу 1:

Лістинг 1. Створення двох кешей

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -cp. -Xshareclasses: name = cache1 Hello Hello C: \ j9vmwi3223 \ sdk \ jre \ bin> java -cp. -Xshareclasses: name = cache2 Hello Hello

Запуск подопціі listAllCaches виводить список всіх кешей в системі і визначає, використовуються вони чи ні, як ви можете побачити в лістингу 2:

Лістинг 2. Лістинг всіх кешей

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: listAllCaches Shared Cache Last detach time cache1 Sat Apr 15 18:47:46 2006 cache2 Sat Apr 15 18:51:15 2006 Could not create the Java virtual machine.

Запуск опції printStats представляє висновок статистики за названою кешу, як показано в лістингу 3. Для більш докладного опису того, що означають всі показані поля, зверніться до призначеного для користувача довідником (див. ресурси для посилання).

Лістинг 3. Сумарна статистика для кеша

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: name = cache1, printStats Current statistics for cache "cache1": base address = 0x41D10058 end address = 0x42D0FFF8 allocation pointer = 0x41E3B948 cache size = 16777128 free bytes = 15536080 ROMClass bytes = 1226992 Metadata bytes = 14056 Metadata% used = 1% # ROMClasses = 313 # Classpaths = 2 # URLs = 0 # Tokens = 0 # Stale classes = 0% Stale classes = 0% Cache is 7% full Could not create the Java virtual machine.

Запуск опції printAllStats в названому кеші виводить дійсний зміст кешу, поряд з виведенням інформації printStats. Кожен клас, що зберігається в кеші, знаходиться в списку поряд з контекстні дані такі, як дані шляху класу. У лістингу 4 ви можете побачити список розкрутки шляху класу віртуальної машини Java, за яким слід деякі класи і докладна інформація про те, звідки вони були завантажені:

Лістинг 4. Лістинг повного вмісту кеша

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: name = cache1, printAllStats Current statistics for cache "cache1": 1: 0x42D0FAB0 CLASSPATH C: \ j9vmwi3223 \ sdk \ jre \ lib \ vm.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ core.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ charsets.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ graphics.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ security .jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmpkcs.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmorb.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmcfw.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmorbapi.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmjcefw.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmjgssprovider.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmjsseprovider2.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmjaaslm.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmjaasactivelm.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ ibmcertpathprovider.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ server.jar C: \ j9vmwi3223 \ sdk \ jre \ lib \ xml.jar 1: 0x42D0FA78 ROMCLASS: java / lang / Object at 0x41D10058. Index 0 in classpath 0x42D0FAB0 1: 0x42D0FA50 ROMCLASS: java / lang / J9VMInternals at 0x41D106E0. Index 0 in classpath 0x42D0FAB0 1: 0x42D0FA28 ROMCLASS: java / lang / Class at 0x41D120A8. Index 0 in classpath 0x42D0FAB0 ...

Названі кеші можна знищити за допомогою опції destroy, як показано в лістингу 5. Подібним чином, опція destroyAll знищує всі кеші, які не використовуються і у яких є дозвіл на те, щоб користувач міг їх знищити.

Лістинг 5. Знищення кеша

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: name = cache1, destroy JVMSHRC010I Shared Cache "cache1" is destroyed Could not create the Java virtual machine. C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: listAllCaches Shared Cache Last detach time cache2 Sat Apr 15 18:51:15 2006 Could not create the Java virtual machine.

Опція expire, показана в лістингу 6, є керуючою опцією, яку ви можете додати в командний рядок, щоб автоматично знищити кеші, до яких не було нічого прив'язане як зазначеного числа хвилин. Це одна єдина утиліта, яка не ставати причиною виходу JVM. Лістинг 6 являє кеші, які не використовувалися протягом тижня і тепер їх знищують перед запуском віртуальної машини:

Лістинг 6. Знищення кешей, які не були використані протягом тижня

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -cp. -Xshareclasses: expire = 10000, name = cache1 Hello Hello

вербалізувати опції

Вербалізувати опції надають корисну інформацію про те, що відбувається з класами загального користування. Всі вони є подопціямі -Xshareclasses. Цей розділ пропонує вам кілька прикладів того, як потрібно використовувати вербалізованій висновок даних.

Опція verbose, показана в лістингу 7, надає коротку інформацію про статус процесів запуску та вимикання JVM:

Лістинг 7. Отримання інформації про статус JVM

C: \ j9vmwi3223 \ sdk \ jre \ bin> java -cp. -Xshareclasses: name = cache1, verbose Hello [-Xshareclasses verbose output enabled] JVMSHRC158I Successfully created shared class cache "cache1" JVMSHRC166I Attached to cache "cache1", size = 16777176 bytes Hello JVMSHRC168I Total shared class bytes read = 0. Total bytes stored = 1176392

Опція verboseIO виводить рядок статусу для кожного запиту на завантаження класу в кеш. Щоб зрозуміти те, що виводить опція verboseIO, вам необхідно зрозуміти ієрархію завантажувача класів. Це можна ясно побачити в класах, які завантажуються будь-якою програмою завантаження без розкрутки. Кожен завантажувач класів повинен передавати повноваження на ієрархію завантажувачу розкрутки, щоб той міг знайти клас. При виведенні інформації, кожному завантажувачу класів призначається унікальний номер ID, коли як завантажувач розкрутки завжди має номер 0.

Зауважимо, що це в порядку речей для verboseIO іноді показувати класи, які були завантажені з диска і збережені в кеші, навіть якщо вони вже були збережені в кеші. Наприклад, перша завантаження класів з кожного файлу JAR шляху класів додатки завжди відбувається з диска і зберігатися незалежно від того, чи існує він в кеші чи ні.

В лістингу 8 перша частина показує стан зайнятості кеша, а друга частина показує процес читання класів, збережених в кеші:

Подопція verboseHelper, представлена ​​в лістингу 9 є покращеною опцією, яка видає інформацію про статус з інтерфейсу Помічника API. Вона була створена для того, щоб допомогти розробникам, що використовують інтерфейс Помічника API, зрозуміти, яким чином він запускається. Більш докладно про даному поданні інформації ви можете прочитати в діагностичному довіднику JVM (див. ресурси для посилання).

Модифікація середовища виконання байт-коду

Модифікація середовища виконання байт-коду стає все більш популярним засобом реалізації поводжень в Java-класах. Її можна виконати за допомогою засобів інтерфейсу інструментів JVM Tools Interface (JVMTI) (див. ресурси для посилання). Інакше, перед тим, як клас буде визначено, байти класів можуть бути переміщені загрузчиком класів. Це являє собою великих труднощів у класах загального користування, так як одна JVM може кешувати інструментований байт-код, який не повинен бути завантажений інший JVM розділяючи один і той же кеш.

Однак, з причини динамічної сутності реалізації Розділених Класів IBM, комплексні віртуальні машини, що використовують різні типи модифікації можуть безпечно розділяти один і той же кеш. Більш того, якщо модифікація байт-коду ресурсоємності, кешування модифікованих класів навіть набагато виїгришней, так як трансформацію необхідно виконати тільки один раз. Єдина умова в тому, що модифікації байт-коду повинні бути передбачуваними, і їх можна було визначити. Після того, як клас був модифікований і збережений в кеш, його більше не можна змінювати.

Модіфікованій байт-код можна розділяті с помощью подопціі modified = <context> опції -Xshareclasses. Контекст є ім'ям, опис користувачем, что створює сегмент в кеші, в якому зберігаються всі завантажені JVM класи. Всі віртуальні машини, що використовують дану модифікацію, повинні використовувати відповідне контекстне ім'я модифікації. Також всі вони завантажують класи з одного і того ж сегмента. Будь-яка JVM, що використовує той же кеш без подопціі modified знаходить і зберігає в собі уніфіковані класи, як нормальні.

потенційні небезпеки

Якщо JVM запускається з агентом JVMTI, який зареєстрував команду модифікувати байти класів і подопція modified не використовується, то поділ класів з іншими уніфікованими віртуальними машинами або тими, які використовують інших агентів, відбувається все ще безпечно, проте, з малим якістю виконання з- через додаткові перевірки. Таким чином, раціональніше всього використовувати подопцію modified.

Зауважимо, це можливо тільки через те, що JVM знає, що модифікація байт-коду неминуча внаслідок існування агента JVMTI. Тому, якщо для користувача завантажувач класів модифікує байти класів перед тим, як визначити клас без використання JVMTI і без використання подопціі modified, що визначаються класи розпізнаються як уніфіковані і внаслідок цього можуть бути невірно завантажені іншими віртуальними машинами.

За більш детальною інформацією про поділ модифікованого байт-коду звертайтеся в діагностичний довідник JVM (див. ресурси ).

Використання інтерфейсу Помічника API

Інтерфейс Помічника API Розділених Класів наданий IBM для того, щоб розробники могли інтегрувати підтримку класів загального користування в призначені для користувача завантажувачі класів. Ця вимога тільки для завантажувачів класів, що не розширюють java.net.URLClassLoader, в порівнянні з завантажувачами автоматично успадковують підтримку класів загального користування.

Дана стаття не є вичерпним підручником по інтерфейсу Помічника API, так як в ній лише загальний огляд теми. Якщо ж вам необхідно докладний опис, повна документація по Java доступна в розділі Download , І також ви знайдете додаткову інформацію в діагностичному довіднику (див. ресурси ).

Хорошим прикладом для користувача завантажувач класів в середовищі розробки є OSGi, який використовується в Eclipse 3.x. Якщо підтримка класів загального користування не додана до завантажувач класів плагіна OSGi, єдині класи, які будуть розділеними - це класи розкрутки і класи додатки, яким потрібно запустити під середовищами Eclipse і OSGi. Жоден з кодів плагінів може бути розділений, так як вони завантажуються для користувача завантажувачами класів плагіна OSGi, у яких немає підтримки класів загального користування. Слід зазначити, що в особливих випадках IBM надає плагін Адаптор OSGi для того, що активувати підтримку класів загального користування в завантажувач класів плагіна. Він доступний в файлі з назвою com.ibm.cds_1.0.0.zip, який ви можете придбати в розділі Download .

Інтерфейс Помічника API: Короткий виклад

Всі класи інтерфейсу Помщніка API знаходяться в пакеті com.ibm.oti.shared і міститися всередині vm.jar в директорії jre / lib. Кожен з загрузчиков класів, який буде розділяти класи повинен отримати об'єкт SharedClassHelper з SharedClassHelperFactory. Створений вами SharedClassHelper належить до завантажувача класів, який запитує його і може тільки зберігати класи, визначені цим завантажувачем класів. SharedClassHelper дає завантажувачу класів простий інтерфейс API для пошуку і зберігання класів в кеші класів, до якого підключена JVM. Якщо в засобі завантаження класів проводитиметься утилізація пам'яті, то ставиться до нього SharedClassHelper також проходить процес GC.

Використання SharedClassHelperFactory

SharedClassHelperFactory є одноелементні безліч, яке виходить за допомогою використання статичного методу com.ibm.oti.shared.Shared.getSharedClassHelperFactory (), який повертає factory, якщо в JVM активовано підтримку класів. Інакше, він повертає null.

Використання SharedClassHelpers

Існують різні типи SharedClassHelper, які повертаються factory, кожен з яких створений для того, щоб його могли використовувати різні типи завантажувачів класів:

  • SharedClassURLClasspathHelper: Цей помічник створений для використання завантажувачами класів, в яких закладено концепт URL-шляху класу. Класи зберігаються і розташовуються в кеші за допомогою масиву URL-шляху класів. Джерела URL шляхів класів повинні бути доступні в файлової системі для класів, щоб їх можна було зберегти в кеші. Цей помічник має деякі обмеження на те, як може бути модифікований шлях класу протягом дії даного помічника.
  • SharedClassURLHelper: Цей помічник створений для використання завантажувачами класів, не мають закладений концепт шляху класу і можуть завантажувати клас з будь-якої адреси URL. Дані джерела URL повинні бути доступні в файлової системі для класів, щоб їх можна було зберегти в кеші.
  • SharedClassTokenHelper: Цей помічник фактично перетворює кеш класів загального користування в просту таблицю застарілих даних (hashtable) - класи зберігаються навпаки строкових ключових лексем, які незрозумілі для кеша. Це єдиний помічник, який не надає можливості динамічного оновлення, тому що збережені дані не мають відповідного контексту файлової системи.

Кожен з SharedClassHelper має два базових методи, параметри яких трохи розрізняються в типах помічників:

  • byte [] findSharedClass (String classname ...) повинен бути викликаний після того, як завантажувач класів запросив клас у батька (якщо такий існує). Якщо findSharedClass () НЕ повертає null, то завантажувач класів повинен викликати defineClass () в повертається байтвий масив. Відзначимо, що ця функція повертає спеціальний файл cookie для defineClass (), недійсні байти класу так, що байти неможливо більше реалізовувати.
  • boolean storeSharedClass (Class clazz ...) повинні бути викликані негайно після визначення класу. Метод повертає true, якщо даний клас був успішно збережений, в іншому випадку він повертає false.

інші випадки

Коли ви застосовуєте класи загального користування в своєму додатку, вам необхідно враховувати такий фактор, як безпека, а також налаштування кеша. Нижче наведені більш зрозумілі міркування.

Безпека

У стандартному налаштуванні, кеші класів створюються з призначеним для користувача рівнем безпеки, таким чином, тільки користувач, який створив цей клас, має до нього доступ. З цієї причини, стандартне ім'я кеша відрізняється для кожного користувача, і розбіжностей в цьому плані немає. В UNIX існує подопція для настройки groupAccess, яка надає доступ усім користувачам у вихідній групі користувачів, які створили цей кеш. Однак, незважаючи на використовуваний рівень доступу, кеш може бути знищений тільки користувачем, який створив його, або адміністратором.

На додаток до цього, якщо встановлено SecurityManager, то завантажувач класів може лише розділяти класи, коли йому явно задали відповідні права доступу. Звертайтеся до призначеного для користувача довідником (див. ресурси ) За більш детальною інформацією про встановлення прав доступу.

Утилізація пам'яті і синхронне компіляція

Робота з класами загального користування ніяк не впливає на процес утилізації пам'яті (GC). Класи і завантажувачі класів також проходять утилізацію пам'яті, як і в разі класів загального користування. Також при активованих класах загального користування у методів GC немає ніяких обмежень або конфігурацій.

У кеші класу неможливо кешувати синхронно (JIT) скомпільований код, тому при активованому поділі класів в синхронності немає ніяких змін.

Межі розмірів кешу

Поточний теоретичний максимальний розмір кешу дорівнює 2 ГБ. Розмір кешу обмежений наступними факторами:

  • Доступне простір на диску (тільки для Microsoft Windows). Файл розподілу пам'яті створюється в директорії під назвою javasharedresources для зберігання даних класів. Ця директорія створюється в призначеній для користувача директорії% APPDATA%. Файли класів загального користування знищуються кожен раз, коли ви перезапускаєте систему Windows.
  • Доступне простір в системі (тільки для UNIX). В UNIX кеш знаходиться в розділеної пам'яті і файл конфігурації записується за допомогою JVM в / tmp / javasharedresouces, щоб дати доступ усім віртуальним машинам розподіляти розділені області пам'яті поімененно.
  • Доступне ВАП. У зв'язку з тим, що віртуальний адресний простір процесора розділяється між кешем класів загального користування та динамічною пам'яттю Java, збільшення максимального розміру динамічної пам'яті Java зменшує розмір кешу класів загального користування, який ви хочете створити.

приклад

Щоб продемонструвати вам переваги поділу класів на практиці, в цьому розділі представлено просте демо (demo) в графіку. Вихідні дані і двійкові коди доступні в розділі Download .

Демо-додаток шукає директорію jre \ lib і відкриває всі файли JAR, під назвою class.forName (), в кожному з знайдених класів. Внаслідок цього приблизно 12000 класів повинні бути завантажені віртуальною машиною. Демо видає звіти про те, як багато часу потрібно JVM, щоб завантажити класи. Очевидно, що це досить надуманий приклад, так як в ньому проводиться лише завантаження класів. Зате даний приклад відмінно демонструє переваги класів загального користування. Давайте запустимо додатком і подивимося на результати.

Якість завантаження класів

  1. Скачайте shcdemo.jar з розділу Download .
  2. Запустіть тест пару раз без поділу класів для розігріву кеша системного диска за допомогою команди, наведеної в лістингу 10:
    Лістинг 10. Розігрів кеша системного диска
    C: \ j9vmwi3223 \ sdk \ jre \ bin> java -cp C: \ shcdemo.jar ClassLoadStress
    Коли з'явиться таке вікно, як на рисунку 1, натисніть кнопку. І додаток завантажить класи.
    Малюнок 1. Натисніть кнопку
    Технологія Java, стиль IBM   Властивість поділу класів допомагає зменшити займане місце в пам'яті і поліпшити початковий запуск програми   Серія контенту:   Цей контент є частиною # з серії # статей: Технологія Java, стиль IBM   https://www
    Як тільки завантаження класів завершилася, додаток видасть звіт про те, скільки класів воно завантажила і скільки часу для цього було потрібно, як показано на рисунку 2:
    Малюнок 2. Ось і результати!

    Ви помітите, що додаток, ймовірно, трохи прискорюється при кожному новому запуску. Це відбувається завдяки оптимізації операційної системи.
  3. Тепер запустіть демо з активованим поділом класів, як показано в лістингу 11 . Створюється новий кеш, і даний запуск програми показує, скільки часу потрібно для заповнення нового кеша. Вам необхідно задати розмір кешу, близько 50MБ, щоб упевнитися, що місця достатньо для всіх класів. Лістинг 11 показує командний рядок і приклад виведення.
    Як зображено на рисунку 3, цей запуск зажадає трохи більше часу, ніж попередні спроби, так як демо заповнює кеш класів загального користування. Ви також на свій розсуд можете використовувати команду printStats, як показано в лістингу 12 для того, щоб подивитися число зберігаються класів в кеші класів загального користування:
    Малюнок 3. Результат не розігрітого кеша
    Лістинг 12. Перегляд декількох кешованих класів
    C: \ j9vmwi3223 \ sdk \ jre \ bin> java -Xshareclasses: name = demo, printStats Current statistics for cache "demo": base address = 0x41D10058 end address = 0x44F0FFF8 allocation pointer = 0x44884030 cache size = 52428712 free bytes = 6373120 ROMClass bytes = 45563864 Metadata bytes = чотиреста дев'яносто одна тисяча сімсот двадцять вісім Metadata% used = 1% # ROMClasses = 12212 # Classpaths = 3 # URLs = 0 # Tokens = 0 # Stale classes = 0% Stale classes = 0% Cache is 87% full Could not create the Java virtual machine.
  4. Тепер запустіть демо знову за допомогою тієї ж самої командного рядка Java. На цей раз воно повинно зчитувати класи з кешу класів загального користування, як можна побачити в лістингу 13 .
    Ви можете чітко побачити значне поліпшення в часі завантаження класів. Тепер ви обов'язково побачите поліпшення якості роботи майже при кожному запуску демо завдяки оптимізаціям операційної системи. Даний тест проходив на однопроцесорному 1.6 GHz x86-сумісних лептопі з Windows XP:
    Малюнок 4. Результати розігрітого кеша

Ви можете експериментувати різними способами. Наприклад, ви можете використовувати команду javaw і запустити кілька демо і на всіх разом запускати завантаження класів, щоб побачити якість паралельної роботи додатків.

Насправді ж загальна перевага часу запуску JVM при використанні класів загального користування залежить від числа класів, що завантажуються додатком: програма HelloWorld не зможе показати помітної переваги, коли як великий веб-сервер дійсно покаже. Однак, даний приклад, напевно, зміг продемонструвати, що таке експериментування з поділом класів дуже ефективно, і вам можна легко доступно можливість тестування тих чи інших переваг.

Простір віртуальної пам'яті

При запуску прикладу програми з більш однієї JVM, вам також легко побачити збереження віртуальної пам'яті.

Нижче ви бачите дві копії екрану з диспетчером задач, отриманих на тому ж комп'ютері, що і в минулих прикладах. На рисунку 5 показано, що було запущено п'ять прикладів демо без класів загального користування. На рисунку 6 показано, що було запущено п'ять демо з активованим поділом класів за допомогою командного рядка, що використовується в попередніх прикладах:

Малюнок 5. П'ять демо без поділу класів
Малюнок 6. П'ять демо з поділом класів

Тепер вам ясно видно, що витрати ресурсів з активованим поділом класів значно нижче. ОС Windows намагається підрахувати витрати ресурсів, складаючи розміри VM разом. У зв'язку з тим, що кількість розділених даних класів в кеші одно близько 45MБ, ви бачите, що використання пам'яті на кожну JVM дорівнює приблизно розміром VM плюс кількість даних класів в кеші.

У даних двох прикладах початкові витрати ресурсів були рівні близько 295MБ. Це означає, що в першому прикладі використовувалося 422MБ, коли як у другому прикладі використовувалося 244MБ - різниця в 178MБ.

Висновок

Нове властивість Підрозділи Класів в реалізації платформи Java версії 5.0, розробленою IBM надає простий і зручний шлях зменшення місця, займаного віртуальної пам'яттю і поліпшити час запуску JVM. У даній статті, ви вивчили, як активувати цю властивість, як використовувати утиліти кеша і як отримувати якісні виміри переваг.

Наступна стаття даного випуску представить вам деякі нові інструменти налагодження, моніторингу та профілювання, які доступні на платформі Java, розробленої IBM. Також в ній ми розповімо про те, як швидко їх можна використовувати при профілювання і налагодженню Java-додатків.

Ресурси для скачування

Схожі тими

Підпішіть мене на ПОВІДОМЛЕННЯ до коментарів

Які частини класу кешуються?
Що відбувається, якщо клас змінюється в файлової системі?
Jsp?
Як кешуються класи?
Які частини класу кешуються?
Що відбувається, якщо клас змінюється в файлової системі?