Ускорьте запуск приложения, добавив собственные классы приложений в classes.jsa - PullRequest
32 голосов
/ 14 января 2011

Чтобы ускорить время запуска JVM, разработчики Sun решили, что было бы неплохо предварительно скомпилировать стандартные классы времени выполнения для платформы во время установки JVM. Эти предварительно скомпилированные классы могут быть найдены, например, по адресу:

$ JAVA_HOME \ JRE \ Bin \ клиент \ classes.jsa

В настоящее время моя компания разрабатывает отдельное приложение на Java, которое имеет собственную JRE, поэтому было бы фантастическим вариантом ускорить время запуска нашего приложения, добавив собственные классы приложений в этот файл jsa.

Я не верю, что файл JSA был создан с помощью магии, поэтому: Как он создается? И как я могу обмануть JVM для включения моих собственных классов?

РЕДАКТИРОВАТЬ : я уже обнаружил следующее:

Class.jsa создается командой

java -Xshare:dump

Список классов для включения в дамп можно найти в $JAVA_HOME/jre/lib/classlist.

Мне даже удалось добавить свои собственные классы здесь (и добавить их в rt.jar для java, чтобы найти их) и сгенерировать мою собственную контрольную сумму ниже файла списка классов.

Последняя проблема: только классы в пакетах java, com.sun и org.w3c, похоже, распознаются, если я оставлю те же классы в их исходных пакетах, они не будут загружены. Я искал указатель об этом во всем исходном коде OpenJDK, но, похоже, что-то связано с доменами защиты. Если кто-то достаточно заинтересован в этой теме и обладает достаточными знаниями, пожалуйста, добавьте несколько советов, чтобы я мог продолжить его изучение.

Ответы [ 4 ]

11 голосов
/ 29 января 2013

Вы были почти там, вам нужно всего лишь пара шагов, чтобы это заработало. Чтобы добавить свои собственные классы в clients.js, вам нужно выполнить следующие шаги:

  1. Квалифицированное название ваших классов (у вас оно есть)

  2. classpath этих классов (у вас есть)

  3. Знать, как пересчитать контрольную сумму (она у вас есть)

  4. Создайте дамп нового файла, указав путь к классам, которые вы сейчас прекомпилируете с классами Java.

  5. Запустите программу, указав тот же путь к классам, который вы использовали для выгрузки новых классов. Jsa

Чтобы указать путь к классам, где находятся классы, которые вы добавляете в список классов, используйте команду -Xbootclasspath/a. Он добавит каталоги / JAR, когда JVM ищет места, где находятся загрузочные классы. Пространство по умолчанию для classes.jsa довольно мало, если вам нужно его улучшить, вы можете использовать команды -XX:SharedReadWriteSize и -XX:SharedReadOnlySize. Ваша команда дампа выглядит примерно так:

java -Xshare:dump -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

Последний шаг - просто запустить приложение java в обычном режиме, помня о включении режима общего доступа. Вам также нужно добавить Xbootclasspath в точности как вы добавили в дамп. Это будет выглядеть примерно так:

java myapp.java -Xshare:on -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

Теперь каждый класс, который вы помещаете в список классов, используется совместно с другими экземплярами, работающими в той же JVM.

11 голосов
/ 21 октября 2015

Начиная с Java 8u40 (и Embedded Java 8u51), Java теперь поддерживает совместное использование данных класса приложений (AppCDS) (т.е. ваши собственные классы в общем архиве). На нашей встроенной java мы обнаружили улучшение запуска> 40%! Довольно круто, потому что с нашей стороны почти нет работы ...

https://blogs.oracle.com/thejavatutorials/entry/jdk_8u40_released

8 голосов
/ 14 января 2011

Интересная идея. Хотя, как я прочитал, он используется для обмена данными между виртуальными машинами и для ускорения загрузки классов, а не для компиляции. Я не уверен, какую выгоду вы получите, но, возможно, стоит попробовать, если у вас уже есть большое отставание при запуске (хотя виртуальная машина уже пытается уменьшить это).

Что касается того, чтобы попробовать это самостоятельно, то, похоже, этот файл обычно создается при установке Sun VM, но вы также можете управлять им. Некоторые подробности содержатся в этом более раннем документе Sun Java 5 Class Data Sharing (который вы, возможно, уже видели?). Некоторые документы Sun Java 6 также упоминают об этом несколько раз , но не добавляют много в документацию. Кажется, изначально это была функция IBM VM . И, чтобы продолжить дамп ссылки, это объясняется немного в этой статье .

Лично я не знаю много об этом, поэтому я не знаю, как вы можете это контролировать. Вы можете регенерировать его, но я не думаю, что он предназначен для того, чтобы вы добавляли нестандартные вещи. Кроме того, даже если вы можете «обмануть» его, это, вероятно, нарушит какую-либо лицензию Sun / Oracle (например, вы не можете связываться с rt.jar и распространять). И, несмотря на все сказанное, я сомневаюсь, что вы увидите серьезное улучшение времени запуска, если у вас в приложении не будет тысяч или десятков тысяч классов?

(И это не совсем ответ, я знаю, но он был слишком большим, чтобы уместиться в комментарии, и я нашел вопрос интересным, поэтому я немного исследовал и разместил здесь ссылки на случай, если кто-то найдет эту информацию полезной .)

0 голосов
/ 18 апреля 2018

Понадобилось немного разобраться, но у меня есть 4 виртуальные машины Java8 (версия 1.8.0_162), работающие с использованием общих классов. Следующий скрипт использовался для настройки и тестирования общего доступа и с небольшими изменениями мог использоваться в другом месте:

#!/bin/bash

# Libraries to load
LIBS1="./lib/protobuf-java-2.6.1.jar:\
./lib/jetty-server-9.2.18.v20160721.jar:./lib/jetty-util-9.2.18.v20160721.jar:./lib/servlet-api-3.1.jar:./lib/jetty-http-9.2.18.v20160721.jar:./lib/jetty-io-9.2.18.v20160721.jar:\
./lib/derby.jar:\
./lib/json-simple-1.1.1.jar:"
LIBS2=":./lib/GTFS.jar"

# Uncomment these lines for the first phase where you are determining the classes to archive. During this phase aim to get as many classes loaded as possible
# which means loading a schedule and retrieving the stop list and next vehicle information
#
#APPCDS="-Xshare:off -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:DumpLoadedClassList=../GtfsAppCds.lst"
#java -Xmx512m $APPCDS -Dderby.system.home=database -classpath $LIBS1$LIBS2 com.transitrtd.GtfsOperatorManager

# Uncomment these lines when the class list is created and run to create the shared archive. Classes marked as unverifiable will need to be removed from the
# archived class list in GtfsAppCds.lst and the lines below run again. LIBS2 above contains jars which are left out of the archive. These are jars which change
# frequently and would therefore cause the archive to be frequently rebuilt.
#                                                                                                                                                                                                               
#APPCDS="-Xshare:dump -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedClassListFile=../GtfsAppCds.lst -XX:SharedArchiveFile=../GtfsAppCds.jsa"
#java -Xmx512m $APPCDS -classpath $LIBS1

# Uncomment these lines when wishing to verify the application is using the shared archive.
#
#APPCDS="-Xshare:on -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedArchiveFile=../GtfsAppCds.jsa -verbose:class"
#java -Xmx512m $APPCDS -Dderby.system.home=database -classpath $LIBS1$LIBS2 com.transitrtd.GtfsOperatorManager

Обратите внимание, что файл общего архива (т.е. файл jsa) зависит от архитектуры и должен быть построен на каждом типе целевой платформы.

Также, если в банке используются запечатанные пакеты, возникает исключение безопасности, см.

https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html

для получения информации о запечатанных упаковках. Это было выше, с derby.jar , но проблему можно решить, распаковав файл jar, заменив Sealed: true на Sealed: false в манифесте и упаковать его.

jar-файлы, созданные с использованием более старых версий java, нельзя использовать в общем архиве, в приведенном выше случае версию derby необходимо было обновить с 10.10 до 10.14, чтобы получить выгоду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...