[Лучшее за день] Для программистов так называемое правило 28 означает, что они тратят 80 % времени на изучение принципа 20 %, что не является обычным явлением в повседневных исследованиях и разработках.
Говорят, что один программист в Али очень интересовался каллиграфией и после выхода на пенсию решил добиться некоторых успехов в этой области. Поэтому он потратил много денег, чтобы купить четыре сокровища первоклассного исследования.
Однажды, после еды, внезапно родился Ясин, я отполировал чернила и имитировал бумагу, зажег прекрасное сандаловое дерево, совершенно в стиле Ван Сичжи, и импульс Янь Чжэньцина, на мгновение успокоился, брызнул чернилами и почистил, и торжественно написал строчку: привет мир.
Конечно, это эксклюзивная программистская шутка хахаха.
Итак, вот вопрос: после столь долгого написания Hello World вы уверены, что понимаете принципы, лежащие в основе того, что вы написали? (о≖◡≖)
[Учитывая 2 минуты, эта точка знаний включает в себя процесс выполнения Java-программы, включая компиляцию, загрузку и выполнение. Можете пояснить? 】
Затем введите серьезное время (@ ̄ー ̄@)
Уникальный привет мир
public class Main {
private static String word = "Hello World!";
public static void main(String[] args) {
new Main().say();
}
private void say() {
System.out.println(word);
}
}
Весь процесс выполнения кода можно разделить на три этапа:
- компиляция кода
- загрузка класса
- выполнение класса
компиляция кода
Функция компиляции кода заключается в преобразовании файла Main.java, который мы написали, в файл Main.class. .class здесь также называется файлом байт-кода. Когда вы откроете его, это будет куча марсианских текстов. Мы можем думать о процесс компиляции как процесс создания исходных материалов JVM, а используемым инструментом является инструмент javac, предоставленный jdk. Общий процесс выглядит следующим образом:
- лексический анализ, то есть процесс преобразования потока символов исходного кода в набор токенов. Согласно народному описанию, в нашем реальном программировании один символ является наименьшей единицей, но на самом деле в процессе программирования токен является наименьшей единицей, такой как ключевые слова, имена переменных, литералы, операторы и т. д. могут стать Токены, кажется Это все еще немного обманчиво, например (>﹏
Этот процесс фактически полностью экранирован для нас, но на самом деле это принцип современной классической компиляции. Подпрограммы, лексический анализ также для подготовки к последующей компиляции]
- Разбор, после получения набора токенов с помощью лексического анализа следующим шагом является построение абстрактного синтаксического дерева.Так называемое абстрактное синтаксическое дерево на самом деле представляет собой древовидное представление, используемое для описания синтаксической структуры программного кода, в котором каждый узел синтаксиса дерево представляет собой синтаксическую структуру в программном коде, такую как пакет, тип, модификатор, оператор и т. д.
В наших глазах main.java может четко понять, что написано, но для JVM это все еще является лицом, поэтому он должен быть построен как дерево грамматики. После этого шага это не будет другого исходного файла. Операция, Последующая работа построена на абстрактном синтаксическом дереве
-
Заполнить таблицу символов, таблица символов представляет собой таблицу, состоящую из набора адресов символов и информации о символах.Эта таблица будет использоваться на разных этапах компиляции.Например, на этапе генерации объектного кода будет выделен адрес имени символа, и таблица символов - это распределение адресов в соответствии с.
-
Семантический анализЭтап семантического анализа также можно назвать этапом семантического обнаружения.Как упоминалось выше, синтаксический анализ будет строить синтаксическое дерево, поэтому правильность и разумность синтаксического дерева определяется семантическим анализом.Анализ потока данных и управления проверки выполняются в два этапа, а информация проверяется на последнем этапе генерации байт-кода.
-
генерация байткода, Это последний этап процесса компиляции javac. Этап генерации байт-кода — это не просто процесс преобразования информации, сгенерированной на предыдущих шагах, в байт-код и размещение ее на диске. наш собственный перегруженный конструктор.
время компиляцииЭто конец этого, поэтому кто будет передавать это сырье для виртуальной машины JVM? На этот раз мы должны посмотреть на процесс загрузки класса.
загрузка класса
Загрузка класса — это просто загрузка скомпилированного файла байт-кода [Main.class] загрузчиком классов в виртуальную машину. , то естественно, мы должны сначала ввести следующие четыре вида загрузчиков
Разговор о четырех классах загрузчиков
Как видно из приведенного рисунка, загрузчики классов можно разделить на четыре типа, причем четвертый тип реализуем мы сами, так какие еще три типа загрузки классов предоставляет JVM в процессе запуска программы Main? это делает?
Прежде всего, давайте поговорим о Bootstrap ClassLoader, загрузчике классов запуска.Основная функция загрузчика классов запуска — загрузить библиотеку классов %JAVA_HOME%\jre\lib\rt.jar и загрузить ее в память виртуальной машины.Затем в библиотеке классов rt.jar есть Что она делает? rt.jar содержит базовую библиотеку классов Java, то есть файлы классов всех классов, показанных в документе Java. Заинтересованные друзья могут открыть каталог, чтобы увидеть его.
Второй — загрузчик классов расширений Extension ClassLoader , роль загрузчика классов расширений в основном отвечает за загрузку всех библиотек классов в каталоге JAVA_HOME\jre\lib\ext, в основном для загрузки пакета расширения.
Кроме того, ClassLoader Applicater System Class Class, также известный как погрузчик класса приложений, отвечает за загрузку библиотеки классов, указанной в пути класса пользователей (то есть настроенную мы настроили), которая является загрузкой класса по умолчанию в приложении.
После прочтения краткого описания процесса трех вышеприведенных загрузчиков классов, есть ли способ, наконец, узнать окончательную функцию среды jdk, которую мы настроили?Да, это позволить загрузчикам классов распознавать и загружать различные библиотеки классов.
Так вот вопрос? Какой загрузчик классов загрузил нашу программу Hello World? Да, Application ClassLoader, загрузчик классов по умолчанию в приложении.
Зная загрузчик классов, вы должны понимать, как загружается загрузчик классов, верно?
Расскажите о процессе загрузки класса
Нашел в интернете картинку, простую и понятную.Хотя это просто и понятно, это действительно очень важно, потому что это горячая точка для интервью (✿◡‿◡)
нагрузка
По сути, упомянутый выше системный загрузчик классов Application ClassLoader загружает в память скомпилированный файл Main.class.
[Думаю] Чтобы кинуть вопрос, так называемая загрузка в память, мы все знаем, что JVM делит память на несколько модулей, так в какой модуль она загружается? Горячие вопросы интервью, ответы в конце статьи!
Ссылка на сайт
Ссылка содержит трилогию, общая роль которой заключается в том, чтобы отвечать за объединение двоичных данных Main.class в JRE.
Что касается трилогии, то ее на самом деле очень легко понять;
прежде всегоэтап проверки, загрузчик классов загружает в виртуальную машину бинарный байтовый поток, который необходимо проверить, чтобы не поставить под угрозу безопасность самой виртуальной машины, что также является ценностью этапа проверки;
Далееэтап подготовки, на этапе подготовки формально выделяется память для переменных класса и устанавливаются значения переменных класса по умолчанию, как в программе HelloWorld выше
private static String word = "Hello World!";
Обратите внимание, что первая, которую я описываю, — это переменная класса, которая представляет собой переменную, описываемую static, а вторая — это значение по умолчанию, которое является значением по умолчанию слова выше, null, если это число, то оно равно 0.
Ну наконец тофаза синтаксического анализа, функция фазы синтаксического анализа в основном состоит в том, чтобы заменить символические ссылки в пуле констант прямыми ссылками Фаза синтаксического анализа на самом деле немного сложна для понимания, по крайней мере, сложнее для понимания, чем две вышеуказанные фазы, я постараюсь быть максимально прямолинейным здесь;
Так называемая символическая ссылка относится к строке, содержащей такую информацию, как информация о классе, имя метода, параметры метода и т. д. При первом запуске JVM извлечет соответствующую запись метода в соответствии с этой строкой строки и в порядке для загрузки Вам не нужно выполнять тот же поиск снова, и символическая ссылка будет заменена прямой ссылкой при первом запуске, так что определенное количество потребления может быть сохранено позже; прямая ссылка здесь на самом деле относится к смещению, и виртуальная машина может найти запись метода напрямую через смещение, и поиск не требуется.
инициализацияНаконец-то мы подошли к этапу инициализации. Выше мы упоминали, что значение слова по умолчанию равно null, что является значением по умолчанию, назначенным системой. На этапе инициализации мы искусственно инициализируем переменные класса и другие ресурсы. Например, слово выше используется мной Инициализируется как "Hello World!".
выполнение класса
Выше упоминалось, что Main.class загружается в память виртуальной машины Java, затем следующим шагом является процесс выполнения. Так кто же будет осуществлять этот процесс? Как показано
- подсистема загрузки классов
- подсистема исполнительного механизма
- подсистема сбора мусора
Очевидно и понятно, подсистема загрузки классов на рисунке была рассмотрена выше, а за выполнение этой части отвечает подсистема механизма выполнения, так что же представляет собой процесс?
На самом деле это очень просто, исполняющий движок преобразует байт-код в машинный код [что? Даже конвертировал. Пожалуйста, , байт-код — это язык, распознаваемый JVM, а машинный код — это язык, который, наконец, распознается операционной системой]
Тогда операционная система действительно может его вызывать.Многие люди, которые изучают или делают Java, слышали о JIT, но они не знают, для чего он нужен.Это вы правы.
Наконец, это можно объяснить здесь.Для завершения перевода байт-кода в машинный код используется компилятор JIT (Just In Time) (компилирует весь горячий код) и интерпретатор байт-кода Java (интерпретирует байты построчно). Вот рабочий процесс компиляции JIT:
Байт-код JVM -> машинно-независимая оптимизация -> промежуточный код -> машинно-зависимая оптимизация -> промежуточный код -> распределитель регистров -> промежуточный код -> генератор целевого машинного кода -> целевой машинный код
Наконец, механизм выполнения найдет метод входа main() и выполнит в нем инструкции байт-кода.
Наконец, о процессе выполнения HelloWorld объяснение в основном завершено.Что касается проблемы выделения памяти JVM во время выполнения программы, это относительно большой модуль.Для получения подробной информации, пожалуйста, обратите внимание на общедоступную учетную запись, и мы поговорим об этом в следующий раз! ! !
[Размышления и путаница] После завершения фазы загрузки виртуальная машина сохраняет двоичный поток байтов Main.class в области методов в соответствии с форматом, требуемым виртуальной машиной, а затем создает экземпляр объекта java.lang.Class. class в памяти, в качестве внешнего интерфейса для программ для доступа к этим типам данных в области методов, экземпляры объектов класса java.lang.Class также хранятся в области методов.
Основная деятельность официального аккаунта: технические пояснения, связанные с программированием на стороне сервера, подробности вы можете найти в исторических статьях.
Официальная сторона учетной записи: все виды чатов, включая технологии, работу, жизненный опыт, жизнь в колледже, внутреннее продвижение и т. д.
Добро пожаловать на внимание, давайте поговорим о горах вместе