JVM介绍
Posted 小布丁value
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM介绍相关的知识,希望对你有一定的参考价值。
1.JVM基础知识
1.Java的跨平台性
JVM是用C/C++开发,编译生成机器码,不能快平台,不同的平台需要安装不同的JVM。
1.Java源码带编译会生成和平台无关的字节码.class文件,
2.Java工具会把同一的.class文件,加载到对应的JVM,又因为JVM是和这个系统对应的
实现了”一次编译、到处运行的目的
'实现跨平台是Java程序,不是JVM"
2.JRE/JDK/JVM介绍
JRE(Java Runtime Environment,Java运行环境)也称之为Java平台,所有的Java程序都在JRE下才能运行
JDK(Java Development Kit,Java开发工具包),程序开发过程中需要编译,调试java程序用到的工具包,JDK的工具包也是Java程序,也需要在JRE上运行,为了保证JDK的独立性和完整性,在JDK的安装过程中,JRE也是安装的一部分,所以,在JDK的安装目录下有一个jre目录,存放JRE文件
JVM(Java Virtual Machine)即Java虚拟机
是JRE的一部分 ,它是一个虚构出来的计算机,是通过在实际计算机上仿真模拟各种计算机功能类来实现的,JVM有自己完整的硬件结构,处理器,堆栈,寄存器等,还有相应的指令系统,Java语言最重要的特点就是跨平台运行,使用JVM就是为了支持与操作系统无关,实现跨平台。
3.JVM的生命周期
java虚拟机实例通过调用某个初始类来main方法来运行Java程序,main()必须是共有的(public)、静态的(static)、返回值为void,并且接收一个字符串数组作为参数,任何拥有面方法的类都可以作为Java程序的运行起点
当前mian方法程序执行结束,JVM实例也随之消亡
JVM的工作过程
Java代码如何执行的
JVM的工作过程
加载类的整个过程分成3个子系统:
类加载系统(ClassLoader SubSystem)
运行时数据区(RUntime Data Area)
执行引擎(Execution Engine)
1、类加载子系统
Java类状态过程包含三部分,装载、链接、初始化
装载:主要功能完成是类加载,通过BootStrap ClassLoader、Extension classLoader及Application ClassLoader加载器和双亲委派模型完成特定类加载
链接:
验证:字节码验证器将验证生成的字节码是否正确,如果验证失败,将得到验证失败提示
准备:对于所有静态变量,内存将分配内存空间并给定初始值
解析:所有的符号引用转化为方法区内的原始引用
初始化:
将静态变量赋予原始值
2、运行时数据区域
线程共享
方法区:类级别数据、静态编码 ,线程共享区域
堆区:创建对象及数组存储位置,线程共享区域
运行常量池
线程私有
虚拟机栈:线程私有区域
本地方法栈:存储是调用的额native的方法,线程私有区域
程序计数器:指示代码执行的位置,线程私有的区域
3、执行引擎
执行引擎将运行时数据区域存储的字节码交由执行引擎执行,执行引擎读取字节码并逐个执行
Object o = new Object();
类加载机制
Java中类加载是需要加载编译之后的.class的字节码文件,JVM虚拟机通过解释器能够将字节码解释为特定机器上的机器码
Java源代码 ->编译器->字节码->JVM->机器码
1、类加载时机
虚拟机规范中严格规定6种情况必须立即对类加载并初始化
● 创建对象实例,new 对象的时候,会对类初始化,前提是类没有被初始化过
● 通过class文件反射创建对象
● 调用类的静态属性或给静态属性赋值 XXXX.instance;
● 调用类的静态方法
● 虚拟机启动时被标识为启动的类:比如main方法所在类
● 初始化一个类的子类,使用子类的时候需要先初始化父类 super();
注:Java的类的加载是动态的,并不会一次性将所有的类全部加载后再执行,保证程序运行的基本类完全加载JVM中,至于其他类,在需要时在加载,可以节省内存
不会被加载的情况:
● 在同一个类记载其下面一个类只会被初始化一次,如果已经被初始化了就不必在被初始化
● 在编译是能确定下来的静态变量,不会对类进行初始化,比如final修饰的静态变量
2、类加载器
负责将字节码加载到内存
类加载器
JVM中提供了3种类记载器:各自职责:
BootStrap ClassLoader:负责加载jre/lib/rt.jar里所有的class,由C++实现的,不是ClassLoader的子类
Extension classLoader:负责加载扩展功能的jar包,指jre/lib/*.jar或者是-Djava.ext.dirs指定目录下的jar
Application ClassLoader:负责加载classpath中指定的jar及目录中的class
双亲委派模型的工作过程如下:
1、当前类加载器从自己已经加载的类中’查询是否此类已经加载’,如果已经加载则返回原来已经加载的类。
2、如果没有找到,就去’委托父类加载器去加载’父类加载器也会采用’同样的策略’,查看自己已经加载过的类中是否包含这个类,有就返回,没有’就委托其父类去加载’,直到委托到启动类加载器为止。因为如果父类加载器为空了,就代表使用’启动类加载器’作为父加载器去加载该类。(也就是看到的String类加载器为null)
3、如果’启动类加载器加载失败’,就会使用扩展类加载器来尝试加载,继续失败则会使用AppClassLoader来加载,继续失败就会抛出一个异常’ClassNotFoundException’.
双亲委派的好处:
1、避免类的重复加载
2、安全性,避免用户自己编写的类动态的替换Java的核心类。
以上是关于JVM介绍的主要内容,如果未能解决你的问题,请参考以下文章