Для чего Java-программисты прибегают к native методам? Иногда, чтобы воспользоваться сторонней DLL библиотекой. В других случаях, чтобы ускорить критичный алгоритм за счет оптимизированного кода на C или ассемблере. Например, для обработки потокового медиа, для сжатия, шифрования и т.п.
Но вызов native метода не бесплатен. Порой, накладные расходы на JNI оказываются даже больше, чем выигрыш в производительности. А всё потому, что они включают в себя:
- создание stack frame;
- перекладывание аргументов в соответствии с ABI;
- оборачивание ссылок в JNI хендлы (
jobject
); - передачу дополнительных аргументов
JNIEnv*
иjclass
; - захват и освобождение монитора, если метод
synchronized
; - «ленивую» линковку нативной функции;
- трассировку входа и выхода из метода;
- перевод потока из состояния
in_Java
вin_native
и обратно; - проверку необходимости safepoint;
- обработку возможных исключений.
Но зачастую native методы просты: они не бросают исключений, не создают новые объекты в хипе, не обходят стек, не работают с хендлами и не синхронизованы. Можно ли для них не делать лишних действий?
Да, и сегодня я расскажу о недокументированных возможностях HotSpot JVM для ускоренного вызова простых JNI методов. Хотя эта оптимизация появилась еще с первых версий Java 7, что удивительно, о ней еще никто нигде не писал.
Читать полностью »