目录
java虚拟机特点:
1、一次编译,到处运行
2、自动垃圾回收
3、自动内存管理
jvm整体结构
java代码执行流程
jvm架构模型:栈的指令集架构,寄存器的指令集架构,栈管运行,堆管存储
总结:由于跨平台性的设计,Java的指令是根据栈来设计的。
栈:跨平台性,指令集小,指令多,编译器容易实现,执行性能比寄存器差
生命周期
虚拟机的启动:
java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(inittal class)来完成的,这个类是虚拟机的具体实现指定的。
虚拟机的执行:
程序执行开始虚拟机运行,程序结束它就停止。真真正正执行的是一个叫Java虚拟机的进程。
虚拟机的退出:
(1)程序正常执行结束,(2)程序执行过程中遇到了异常或错误而异常终止,(3)由于操作系统出现错误而导致Java虚拟机进程终止,(3)在代码中主动结束进程,调用Runtime类或System类的exit方法,或者Runtime类的halt方法,并且安全管理器也允许exit或halt操作。
Jit即使编译器,通过计数器将热点代码编译成机器指令缓存起来,提高效率
解释器:逐行解释字节码编译成机器指令
类的加载过程:
加载 --> 链接(验证 --> 准备 --> 解析) --> 初始化
一、loading(加载)
1、通过一个类的全类名获取定义此类的二进制字节流
2、将这个字节流所代表的静态存储结构化转化为方法区的运行时数据结构
3、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据结构的访问入口
加载.class文件的方式:
1.从本地系统中直接加载,2.通过网络获取(web applet),3.从zip压缩文件中获取,4.运行时计算生成(动态代理),5.由其它文件生成(jsp),6.从专有数据库中提取7.从加密文件中获取,典型防class文件被反编译的保护措施。
二、LInking(链接)
验证(Verify):目的在于确保class文件的字节流包含的信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。 文件格式验证、元数据验证、字节码验证、符号应用验证
准备(Perpare):为类变量分配内存并且设置该类的变量的默认初始值,及零值。
例:static int a = 1; prepare:a = 0 ==>> initial: a = 1
解析(Resolve):在初始化之后完成,将常量池内的符号引用转换为直接引用的过程。
事实上,解析操作往往会伴随着JVM在执行完初始化之后再执行。
直接引用就是直接指向目标的指针、相对位偏移量或一个间接定位到目标的句柄。
三、初始化
初始化阶段就是执行类构造器方法 <clinit>() 的过程。
构造器方法中指令按语句在源文件中出现的顺序执行
<clinit>() 不同于类的构造器<init>()。
若该类具有父类。JVM会保证子类的 <clinit> () 执行前,父类的<clinit> () 执行完毕
虚拟机必须保证一个类的 <clinit>() 方法在多线程下被同步加锁
类加载器的分类:
引导类加载器、自定义加载器
四类类加载器是包含关系(从大到小):
bootstrap ClassLoader(C/C++引导/启动类加载器,无法获取),Extension ClassLoader(扩展类加载器),AppClassLoader(系统/应用类加载器),user 自定义类加载器
ClassLoader类:它是一个抽象类,所有的类加载器都继承于ClassLoader(但不包括Bootstrap ClassLoader)
双亲委派机制
一个类加载器收到类加载请求,首先会将请求交给父类加载器,依次递归到最上层加载器,如果不在上层加载器的加载范围(核心包),则会向下反哺,让子加载器加载。
优势:(1)避免类的重复加载(2)保护程序安全,防止核心API被篡改
在JVM中表示两个Class对象是同一个类的必要条件:
(1)类的完整类名一致,包括包名
(2)加载这个类的 类加载器必须相同