Все программы имеют среду выполнения. Мы склонны забывать это, но его там. Стандартная библиотека для C, которая упаковывает системные вызовы в операционную систему. Objective-C имеет среду выполнения, которая оборачивает всю передачу сообщений.
В Java среда выполнения - это JVM. Большинство реализаций Java, с которыми знакомы люди, похожи на JVM HotSpot, который является интерпретатором байтового кода и JIT-компилятором.
Это не должно быть единственной реализацией. Ничто не говорит о том, что вы не можете построить стандартную среду выполнения lib-esque для Java, скомпилировать код в машинный код и запустить его в среде выполнения, которая обрабатывает вызовы новых объектов в malloc и доступ к файлам в системные вызовы на машине. И это то, что делает компилятор Ahead Of Time (AOT, а не JIT). Называйте эту среду выполнения как хотите ... вы можете назвать это реализацией JVM (и она действительно следует спецификации JVM) или средой выполнения или стандартной библиотекой Java для Java. Его там и он делает то же самое.
Это можно сделать, либо переопределив javac
целевую машину (это то, что сделал GCJ ). Или это можно сделать с помощью перевода байт-кода, сгенерированного с помощью, javac
в машинный (или байтовый) код для другой машины - это то, что делает Android. Основанный на Википедии , это то же самое делает Excelsior JET («Компилятор преобразует переносимый байт-код Java в оптимизированные исполняемые файлы для требуемого оборудования и операционной системы (ОС)»), и то же самое относится и к RoboVM .
С Java есть дополнительные сложности, которые означают, что это очень трудно сделать как эксклюзивный подход. Динамическая загрузка классов ( class.forName()
) или прокси-объектов требует динамики, которую компиляторы AOT не могут легко обеспечить, поэтому их соответствующие JVM должны также включать в себя JIT-компилятор (Excelsior JET) или интерпретатор (GCJ) для обработки классов, которые не могут быть предварительно скомпилированы в родной.
Помните, что JVM является спецификацией , со многими реализациями . Стандартная библиотека C также является спецификацией с множеством различных реализаций.
С Java8 была проделана большая работа по компиляции AOT. В лучшем случае можно обобщить АОТ в целом только в пределах текстового поля. Тем не менее, на Языковом саммите JVM в 2015 году (август 2015 года) была представлена презентация: Java Goes AOT (видео на YouTube). Это видео длится 40 минут и раскрывает многие более глубокие технические аспекты и показатели производительности.
gcj
минимальный работоспособный примерВы также можете наблюдать реализацию с открытым исходным кодом, как
gcj
(в настоящее время устарела). Например, файл Java:Затем скомпилируйте и запустите:
Теперь вы можете декомпилировать его и посмотреть, как оно работает.
file Main.o
говорит, что это файл эльфа.readelf -d Main | grep NEEDED
говорит, что это зависит от динамических библиотек:Таким образом, libgcj.so должен быть там, где реализована функциональность Java.
Затем вы можете декомпилировать его:
и посмотреть, как именно это реализовано.
Очень похоже на C ++, много искажений имен и косвенных вызовов полиморфных функций.
Интересно, как начинается сборка мусора. Стоит посмотреть: /programming/7100776/garbage-collection-implementation-in-compiled-languages и другие скомпилированные языки с GC, такие как Go.
Протестировано на Ubuntu 14.04, GCC 4.8.4.
Также взгляните на https://en.wikipedia.org/wiki/Android_Runtime , основу Android 5 и более поздних версий, которая полностью поддерживает AOT для оптимизации приложений Android.
источник