You do not know the principles Hello World Behind

Ali reportedly very interested in calligraphy on a programmer, decided to retire to accomplish something in this regard. So spend big money buying the finest four treasures.

One day, after a meal emergent Masaoki, some Surusumi proposed paper, and lit a sandalwood on the good, quite Wang Xizhi style, but also with Yen Chen momentum, looking hard moment, ink brush, solemnly wrote his words: hello world.

You do not know the principles Hello World Behind

Of course, this is a unique piece of programmers ha ha ha.

So the question is, writing for so long Hello World, we determine their understanding behind what you write is what principle do? (O≖◡≖)

[Given two minutes, the knowledge related to the Java program execution flow, including compilation, loading and execution, if you can clarify it? ]

Next, enter the serious period (@ ¯ ー ¯ @)

Distinctive Hello World

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);
    }
}

Execution of the entire code can be divided into three stages:

  • Code compilation
  • Class loader
  • Class execution

Code compilation

The role is to compile the code we write Main.java files into Main.class file, .class here is also known as byte code file, open a pile of Martian [anyway] is not read, here we can compile the JVM process as raw material production process, using tools javac jdk tool is provided.
Process substantially as follows:

  • Lexical analysis , character is about to become the source of the transfer process Token set. Under the vernacular description is at our actual programming, the smallest unit is a single character, but actually in the programming process, is the smallest unit mark, such as keywords, variable names, literals, operators, and so can become Token, seemingly still somewhat blinded, for example (> ﹏ <), such as in our int integer programming it is three characters, that is, i, n, t three characters, and in the process it is a compilation the Token, not split.

This process is for us, in fact, is fully shielded, but in fact it is a modern classic compiler theory of
routine, but also to give back lexical analysis compiled in preparation]

  • Parsing , get the Token set by lexical analysis, the next step is to construct an abstract syntax tree, called an abstract syntax tree is actually a tree structure describing the program code syntax used to represent a way in which each node of the syntax tree all represent a grammatical structure in the program code, such as bags, type, modifiers, operators and the like.

In our eyes, Main.java already clearly understand what is written in the end, but for the JVM is forced to look ignorant, so it needs to be built into a syntax tree, no longer after this step for source files operation, and subsequent operations are built on the abstract syntax tree

  • Filling the symbol table , the symbol table is a set of tables and symbolic address information composed of symbols, this table will be used at different stages of compilation, the code generation phase as the target, the symbolic name will address allocation, the symbol table is address assignment basis.

  • The semantic analysis , semantic analysis phase can also be said semantic detection phase, the top when it comes to parsing builds a syntax tree, then the tree syntax tree whether it is right and proper, it is done by the semantic analysis, and semantic analysis will be marked by inspection data and control flow analysis and a two-step inspection starts, the last step in the generated check information byte code.

  • Byte code generation , which is the final stage of the compilation process javac byte code generation phase is not just a simple step of converting each of the previously generated information into byte code and then into disks also have a small number and add code conversion work, such as our own overloaded constructor.

Compile to end here, then who is going to transport these materials to the JVM virtual machine do? This time we should look at the process of loading the class.

Class loader

Class loader is simply by the class loader bytecode files compiled] [Main.class loaded into the virtual machine
, so naturally, we must first introduce four types loader

Talk about the four types of loader

You do not know the principles Hello World Behind

As can be seen from the figure above, the class loader can be divided into four categories, while the fourth is by our own realization, then the other three provided by the JVM class loading process we started in the Main program played what role in it?

首先说说启动类加载器 Bootstrap ClassLoader ,启动类加载器的作用主要是加载 %JAVA_HOME%\jre\lib\rt.jar 类库,将其加载到虚拟机内存中,那么rt.jar类库到底有什么作用呢?rt.jar下包含了Java的基础类库,也就是Java doc里面看到的所有的类的class文件,感兴趣的朋友可以自己打开目录看下。

其次是扩展类加载器 Extension ClassLoader ,扩展类加载器的作用主要是负责加载JAVA_HOME\jre\lib\ext目录下的所有类库,主要是载入扩展包。

再者是系统类加载器 Application ClassLoader, 也称之为应用程序类加载器,负责加载用户类路径(也就是我们配置的CLASSPATH)上所指定的类库,是应用程序中默认的类加载。

看完以上三个类加载器的简单描述过程,是不是有种终于知道了我们配置的jdk环境的最终作用了吧,是的,就是让类加载器识别到后加载各种类库。

那么问题来了?是哪个类加载器加载了我们的Hello World程序呢?是的,就是应用程序中默认的类加载器 Application ClassLoader。

知道了类加载器后,那接下来总要了解下类加载器怎么加载的吧?

说说类加载的过程

You do not know the principles Hello World Behind

网上找了张图片,简单明了。虽说是简单明了,不过确实异常重要的,因为是面试热点(✿◡‿◡)

加载

其实就是上文说到的系统类加载器 Application ClassLoader将编译后的Main.class文件加载到内存中。

【思考】抛出个问题,所谓的加载到内存中,我们都知道JVM把内存分成了几大模块,那么请问是加载到哪个模块中?热点面试题,答案见文末

链接

链接中包含了三部曲,总的作用就是负责将Main.class的二进制数据合并到JRE中。

关于三部曲,其实很好理解;

首先是验证阶段,类加载器将二进制字节流加载到虚拟机中,肯定是需要进行验证的,避免危害虚拟机自身安全,而这也是验证阶段存在的价值;

接下来是准备阶段,准备阶段是正式为类变量分配内存并且设置类变量默认值的地方,比如上面HelloWorld程序中的

private static String word = "Hello World!";

注意我描述的第一个是类变量,也就是static所描述的变量,其次是默认值,也就是上面的word的默认值null,如果是数字则为0。

最后是解析阶段,解析阶段的作用主要是将常量池内的符号引用替换为直接引用的过程,解析阶段其实有点难理解,至少是比上面的两个阶段要难理解的,我这里尽量直白点;

所谓的符号引用指的是包含了类的信息、方法名、方法参数等信息的字符串,而当第一次运行时,JVM会根据这行字符串去检索到对应的方法入口,而为了下次不用再做同样的检索,在第一次运行的时候就会将符号引用替换成直接引用,这样后面就可以省去一定的消耗了;这里的直接引用其实就是指偏移量,虚拟机可以通过偏移量直接找到方法入口,不再需要做检索了。

初始化
终于来到初始化阶段了,上面我们有说到word默认值是null,是系统赋的默认值,而在初始化阶段,则是根据我们人为的初始化类变量和其他资源,比如上面的word则被我初始化成了"Hello World!"。

类执行

上面说到Main.class被加载到了Java虚拟机内存中,那么接下来便是执行的过程了。那么由谁来执行这一过程呢?

You do not know the principles Hello World Behind

实际上,一个Java虚拟机在运行的时候可以划分为三个子系统:

  • 类加载子系统
  • 执行引擎子系统
  • 垃圾收集子系统

It is clear, very clear, the figure of the class loader subsystem has been talked about above, the execution engine subsystem is responsible for implementing this part of the process is kind of how it?

Actually very simple, the execution engine will convert bytecode to machine code [what? I still have the conversion. Please <(ˉ ^ ˉ)>, JVM byte code is identified language code is the final byte is the operating system recognized language]

The operating system can really call a lot to learn Java or do people have heard of JIT, but did not know specifically why, exactly that is you.

Here finally explain the byte code into machine code using the translation work is JIT (Just In Time) time compiler (Compiler for the whole hot code) and Java bytecode interpreter (explained byte line by line code) to complete.
Here JIT compiler to the next workflow:

JVM byte code -> machine independent optimization -> intermediate code -> machine-dependent optimization -> intermediate code -> register allocator -> intermediate code -> target machine code generator -> target machine code

Finally, the execution engine to find main () method of this entry, and wherein execution of bytecode instructions.

[Consideration] doubts after loading stage is completed, the virtual machine Main.class binary byte stream in accordance with the storage format in the virtual machine that method area, then the memory of an instantiated object of the class java.lang.Class as the external interface access method program area of these types of data, after the object class java.lang.Class instantiation is stored in the process area.

Guess you like

Origin blog.51cto.com/14295088/2415840