简单介绍一下java程序的运行流程

下面就是jvm虚拟机
正是有了jvm虚拟机才体现了java语言的跨平台性

所以说jvm的作用如下:
java虚拟机是二进制的字节码运行环境,可以运行.class文件。并且解释编译为对应平台的机器指令进行执行。
特点:
目前市面上最常见运用最广泛的是HotSpotVm虚拟机

在虚拟机发展的历程中还有如下的JVM:sun ClassicVM、ExactVm、IBMJ9、AzulVM等等感兴趣的可以去搜索一下,我们主要根据HotSpotVm讲解JVM。

通过javac的编译会生成.class
我们的类加载器就会加载我们电脑磁盘上的class文件,加载到了JVM虚拟机中被称之为DNA原数据模板,存放在方法区中。
就是这个class文件到达jvm成为原数据模板的过程之中需要通过类加载器实现(ClassLoader)。我们的类加载器相当于运输设备。

对于加载的过程细分如下


我们重点解读一下链接 的过程
目的在于确保class文件的字节流中的信息符合虚拟机的要求,保证正确性不会危害jvm虚拟机的运行。
4种验证方式:文件格式验证,原数据验证,字节码原则,符号应用验证
为类的变量分配内存并且设置默认值
这里不包含final修饰的static,因为final在编译的时候就会分配内存
这里不会为实例变量分配初始化,类的变量会分配在方法区中,而实例化的变量会随着对象一起分配到java的堆中
将常量池中的符号引用转换为直接引用过程。
事实上,解析操作往往会伴随着jvm在执行完成初始化之后进行
解析的动作主要是针对类或者接口、字段、类方法、接口方法、方法类型等。
初始化阶段就是执行类构造器方法的过程
此方法不需要被定义,是javac编译器字段收集类中的所有类变量的赋值动作和静态代码中的语句进行合并。

JVM虚拟机支持2中类加载器如下:
自定义类加载 器一般指的是由ClassLoader派生出来的类加载器称之为自定义。

启动类的加载器Jvm虚拟机自带BootstrapClassLoader
这个类加载器是用c语言实现的,嵌套在jvm的内部
他用来加载java的核心类库。
并没有继承java.lang.classLoader没有父类加载器
出于安全考虑Bootstarap启动类加载器只会加载包名为java javax sun等开头的类
java语言编写的加载器
派生于Classloader
父类是启动类加载器
从java.ext.dirs系统属性所指向的目录加载类库,或者从jdk的安装目录的jre/lib/ext子目录下加载类库。如果用户自己创建的jar放在此目录下,也会自动由扩展类加载器进行加载。
由java语言编写
派生于ClassLoader
负责加载变量classpath或者系统属性java.class.path指定路径下的类库
该类加载器是陈故乡默认的类加载器,一般的java应用类都是又他完成加载的
开发人员可以通过继承ClassLoader类的方式实现
在jdk1.2之前要求开发人员继承了ClassLoader的时候要重写loaderClass()方法,但是在jdk1.2之后不建议覆盖loaderClass()方法,而是讲加载的逻辑方法写在FindClass()方法之中。
java虚拟机对class文件采用按需加载的方式,也就是说当需要用到这个类的时候才会将他的class文件加载到内存生成class对象。而且在加载这个对象的class文件的时候,jvm采用的是双亲委派的模式,就是把请求交由父类处理。
工作原理:


Jvm中判断2个class对象是否为同一个类存在以下条件

jvm必须知道一个类型是由启动类加载器加载的还是有用户类型加载器加载的。
1. 如果一个类型是由用户类加载器加载的,那么jvm会将这个类加载器的一个引用作为类型信息的一部分保存着方法区。
2.当解析一个类型得到另一个类型的引用的时候,jvm需要保证这两个类型的加载器是相同的。
java如何使用类


内存是非常重要的系统资源,建立cpu和硬盘中间仓库桥梁。jvm内存布局规定了java在运行过程中的内存申请、分配、管理的策略。保证了jvm的高效稳定,不同的jvm对于内存的划分和管理机制不同这样我们主要也是HotSpotVm。

java的虚拟机定义了若干中程序运行时会使用到的运行时数据区,其中有的一线会随着虚拟机的启动二创建,伴随着虚拟机的退出而销毁。另外一些则是与线程一一对应,这些与线程对应的数据区域会随着线程的生命周期而创建消失。
如下图:

灰色表示为单独现场私有,红色表示多个线程的共享
每个线程:独立包括程序计数器,栈、本地栈。
线程空间共享:堆、堆外内存
