Tag Archives: Mimbolovejdk
Для взаимодействия с 32-разрядной COM библиотекой через jni4net понадобилось, чтобы приложение запускалось с помощью 32-разрядной JDK. Скачал, поставил, и напоролся на то, что установленная 32-битная версия 1.7_25 полностью заменила все имеющиеся JDK, закинув exe-файлы java.exe, javaw.exe прямо в Windows\System32. А мне хотелось, чтобы по умолчанию работала 64-разрядная версия. И только в определённых приложениях запуск производился с помощью 32-битной JVM. Нашел следующее решение:
- Удаляем из System32 три exe файла, появившихся после инсталляции 32-битной JDK
- Устанавливаем JAVA_HOME на 64-разрядную JDK. В Path прописываем путь к директории bin этой же 64-разрядной JDK. Это будет JDK по умолчанию.
- В приложениях, которые требуют запуска с использованием недефолтной JDK, прописываем следующие строки в скрипт запуска:
set JAVA_HOME=путь к JDK
set PATH=%JAVA_HOME%\bin;%PATH%
Вот и всё! Теперь у нас в приложениях, где этих строк нет, будет запускаться дефолтная версия JVM, а в приложениях, которые мы сконфигурировали явно, будет стартовать именно та версия, которую мы прописали.
Навеяно постом http://elizarov.livejournal.com/29052.html – там описывается, как включить опцию дизассемблирования кода скомпилированных методов. Для этого нужно а) найти плагин hsdis и засунуть его в bin-директорию jdk б) запустить приложение со специальными опциями. От себя ещё добавлю пункт в) добиться того, чтобы метод, код которого хочется получить, был скомпилирован JIT-компилятором, а не просто интерпретирован.
Разбираемся с плагином
В посте лежит ссылка на DLL с hsdis плагином, но только для 32-битных систем. У меня 64-битная Windows 8, поэтому пришлось собирать самому. Делал по инструкции с сайта http://dropzone.nfshost.com/hsdis.htm, всё получилось (правда в первые разы почему-то сборка не прошла до конца по причине отсутствия команды gcc, но я доставил в cygwin пакет с gcc-core и всё собралось). Готовые файлы прилагаю: hsdis-amd64.dll и hsdis-i386.dll
Разбираемся с опциями
Вот такую портянку я использовал
-XX:CompileThreshold=1 -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Program.testMethod -XX:PrintAssemblyOptions=intel -XX:+PrintCompilation -XX:+LogCompilation
-XX:CompileThreshold=1 - чтобы JIT-компилятор компилировал методы после одного вызова
-XX:+UnlockDiagnosticVMOptions - нужная опция, чтобы остальные -XX-опции распознавались
-XX:CompileCommand=print,*Program.testMethod - указываем, что нам нужен дизассемблированный листинг метода testMethod класса Program. Зачем тут звездочка, я не понял, может быть потом разберусь
-XX:PrintAssemblyOptions=intel - устанавливает синтаксис, в котором будет выведен дизассемблированный код. Интеловский синтаксис более удобочитаем, поскольку вокруг регистров отсутствуют проценты %eax%
-XX:+PrintCompilation - выводить список методов, которые скомпилированы в нативный код - для отладки того, что наш искомый метод будет скомпилирован
-XX:+LogCompilation - вывести лог компиляции в файл hotspot.log (по умолчанию)
Разбираемся с компиляцией методов
Наблюдая за тем, как работает тестовая программа, я вывел следующие эмпирические заключения. За их корректность не ручаюсь, но судя по экспериментам, дело обстоит именно так. Методы компилируются после выхода из них и компилируются асинхронно, то есть кладутся в некую очередь для JIT-компилятора, и он потом их компилирует. Таким образом, если вы хотите посмотреть листинг метода main(), то навряд ли это у вас получится, потому что сразу же после выхода из main() программа завершится, и JIT-компилятор не успеет её скомпилировать. Я ставил задержки Thread.sleep(1000) после вызова нужного метода, и рантайм успевал скомпилировать его и вывести листинг в лог. Если же вас интересует именно main, то придётся вынести его тело в другой метод, и вызвать его из основного main, добавив после вызова задержку по времени.
1