1、类装载器ClassLoader
(1)负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定
(2)加载类文件进入jvm,四种类加载器
1)启动类加载器(Bootstrap): C++语言编写。
2)扩展类加载器(Extension): Java语言编写。
3)应用程序类加载器(AppClassLoader): Java语言编写,也叫系统类加载器,加载当前应用的classpath的所有类。
4)用户自定义加载器: Java语言编写,Java.lang.ClassLoader的子类,用户可以定制类的加载方式。
(3)双亲委派机制
双亲委派机制加载步骤:
1)当AppClassLoader加载器加载class类时,自己不会马上去加载该class类,会把该class类的加载请求委派给它的父类加载器ExtClassLoader去加载。
2)当ExtClassLoader加载器加载class类时,自己不会马上去加载该class类,会把该class类的加载请求委派给它的父类加载器BootStrapClassLoader去加载。
3)如果BootStrapClassLoader加载器加载失败(在$JAVA_HOME/jre/lib里未查找到该class),才会使用ExtClassLoader加载器来加载class类。
4) 如果ExtClassLoader加载器也加载失败,则会使用AppClassLoader加载器来加载,如果AppClassLoader加载器也加载失败,则会报出异常ClassNotFoundException。
(4) 沙箱安全机制
沙箱安全机制是在双亲委派机制基础上的JVM自我保护机制,如果要写一个java.lang.String 类,根据双亲委派机制的原理,这个请求会先由BootStrapClassLoader加载器尝试进行加载,但是BootStrapClassLoader加载器在加载类时首先通过包和类名查找rt.jar中是否存在该类,如果有则优先加载rt.jar包中的类,因此就保证了java的运行机制不会被破坏。
2、Execution Engine执行引擎
Execution Engine执行引擎负责解释命令,提交操作系统执行。
3、本地方法
(1)Native Interface本地接口
本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C++程序,Java 诞生的时候是 C/C++横行的时候,要想立足,必须有调用 C/C++程序,于是就在内存中专门开辟了一块区域处理标记为native的代码,它的具体做法是 Native Method Stack中登记 native方法,在Execution Engine 执行时加载native libraies。
目前该方法使用的越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用 Socket通信,也可以使用Web Service等等。
(2)Native Method Stack
它的具体做法是Native Method Stack中登记native方法,在Execution Engine 执行时加载本地方法库。
4、PC寄存器
用来存储指向下一条指令的地址,也即将要执行的指令代码。
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。
5、Method Area 方法区
此区属于共享区间。
方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。
静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中。
但是实例变量存在堆内存中,和方法区无关。
6、栈
(1)栈是什么?
栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。8种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配。
(2)栈存储什么?
栈帧中主要保存3 类数据:
1)本地变量(Local Variables):输入参数和输出参数以及方法内的变量。
2)栈操作(Operand Stack):记录出栈、入栈的操作。
3)栈帧数据(Frame Data):包括类文件、方法等等。
(3)栈运行原理
栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧 F1,并被压入到栈中,
A方法又调用了 B方法,于是产生栈帧 F2 也被压入栈,
B方法又调用了 C方法,于是产生栈帧 F3 也被压入栈,
……
执行完毕后,先弹出F3栈帧,再弹出F2栈帧,再弹出F1栈帧……
遵循“先进后出”/“后进先出”原则。
(4)栈的结构是什么?
(5)Stack 栈
(6)栈会出现的错误
调整栈内存大小无法解决这个问题,需要修改错误代码。
7、栈+堆+方法区的交互关系
HotSpot是使用指针的方式来访问对象:Java堆中会存放访问类元数据的地址,reference存储的就直接是对象的地址。
8、JVM历史
(1)三种JVM
- Sun公司的HotSpot
- BEA公司的JRockit
- IBM公司的J9 VM
(2)Hotspot是什么?
Hotspot是jdk的商标。