了解Java的工作原理以帮助自己深入理解java
1.java程序运行图示:
跨平台说明:java编译器 (编译) → 虚拟机(解释执行) → 解释器(翻译) → 机器码这里来说明一下,java经编译生成字节码.class,这是JVM能够理解的语言,JVM 进行解释和执行,然后通过其上的解释器对JVM所做的结果进行翻译,翻译成各自所在平台上的机器码。
2.JVM实现类的加载图示
2.1
--Extension class loader: 这个加载器加载出了基本API之外的一些拓展类,包括一些与安全性能相关的类。
--System Class Loader: 它加载应用程序中的类,也就是在你的classpath中配置的类。
--User-Defined Class Loader: 这是开发人员通过拓展ClassLoader类定义的自定义加载器,加载程序员定义的一些类。
2.2
定义的类在加载之前,虚拟机会先做检查,即所在的命名空间中是否已经存在该类,这种检查方式是自下而上的。在检查报告未发现该类时,最底层(对应图示最顶层)会尝试加载,若未找到该类,就委派给上层加载,该加载过程是自上而下的。
3.加载类后的执行过程
对各步做出简要说明:
Verifying:检查载入的类文件是否符合Java规范和虚拟机规范,例如重写的函数名称,参数相同而返回值类型不同。
Resolving:在类型的常量池中寻找类,接口,字段和方法的符合引用把这些符号引用替换成直接引用的过程
Initialing:初始化类的局部变量,为静态域赋值,同时执行静态初始化块。
4.加载后运行细节
当运行一个JVM示例时,系统将分配给它一块内存区域(这块内存区域的大小可以设置的),这一内存区域由JVM自己来管理。从这一块内存中分出一块用来存储一些运行数据,例如创建的对象,传递给方法的参数,局部变量,返回值等等。分出来的这一块就称为运行数据区域。运行数据区域可以划分为6大块:Java栈、程序计数寄存器(PC寄存器)、本地方法栈(Native Method Stack)、Java堆、方法区域、运行常量池(Runtime Constant Pool)。运行常量池本应该属于方法区,但是由于其重要性,JVM规范将其独立出来说明。其中,前面3各区域(PC寄存器、Java栈、本地方法栈)是每个线程独自拥有的,后三者则是整个JVM实例中的所有线程共有的。
对各区的简易说明:
PC计数器: 每一个线程都拥有一个PC计数器,当线程启动(start)时,PC计数器被创建,这个计数器存放当前正在被执行的字节码指令(JVM指令)的地址。
本地方法栈 :当程序通过JNI(Java Native Interface)调用本地方法(如C或者C++代码)时,就根据本地方法的语言类型建立相应的栈。
运行常量池: 这个区域存放类和接口的常量,除此之外,它还存放方法和域的所有引用。当一个方法或者域被引用的时候,JVM就通过运行常量池中的这些引用来查找方法和域在内存中的的实际地址。
堆(Heap): 堆中存放的是程序创建的对象或者实例。这个区域对JVM的性能影响很大。垃圾回收机制处理的正是这一块内存区域。(Java虚拟机内部会根据一种规则(这个对象是否可以触及)来判断这两个类是否可以回收了?当执行类= null;时这条线就被斩断了,因此类实例就不可以触及了,java虚拟机就可以回收这个类实例了)
声明:这里感谢lovebeauty和Lust-Ring两位博主,我只是当了搬运工,理理思路帮助成长,绝无冒犯!