①java的核心机制java
java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection):python
①Java虚拟机:是运行全部Java程序的抽象计算机,是Java语言的运行环境,在其上面运行Java代码编译后的字节码程序,java虚拟机实现了平台无关性。程序员
②Java垃圾回收(Garbage Collection):自动释放不用对象内存空间,在java程序运行过程当中自动进行,垃圾收集机制可大大缩短编程时间,保护程序的完整性,是Java语言安全性策略的一个重要部份。编程
②java虚拟机及其结构安全
java垃圾回收不须要程序员手动操做,咱们常常须要关注的是java虚拟机,java虚拟机承载着程序从源码到运行的所有工做。
Java虚拟机是可运行Java代码的假想计算机,有本身想象中的硬件,如处理器、堆栈、寄存器等,还具备相应的指令系统,能够执行 Java 的字节码程序。Java语言的一个很是重要的特色就是与平台的无关性。而使用Java虚拟机是实现这一特色的关键。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就能够在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。网络
对于 JVM 的基本结构,咱们能够从下图能够大体了解:数据结构
③程序的运行过程学习
从源文件建立到程序运行,Java程序要通过两大步骤:编译,运行;一、源文件由编译器编译成字节码(ByteCode) 二、字节码由java虚拟机解释运行。spa
①第一步(编译): 建立完源文件以后,程序会被编译器编译为.class文件。Java编译一个类时,若是这个类所依赖的类尚未被编译,编译器就会先编译这个被依赖的类,而后引用,不然直接引用。。编译后的字节码文件格式主要分为两部分:常量池和方法字节码。 .net
②第二步(运行):java类运行的过程大概可分为两个过程:一、类的加载 二、执行。
④类的加载
java程序通过编译后造成*.class文件。经过类加载器将字节码(*.class)加载入JVM的内存中。JVM将类加载过程分红加载,链接,初始化三个阶段,其中链接阶段又可分为验证,准备,解析三个阶段。
)))类加载过程
JVM 的类加载是经过 ClassLoader 及其子类来完成的,类的层次关系和加载顺序能够由下图来描述
①Bootstrap ClassLoader启动类加载器
负责加载$JAVA_HOME中jre/lib/里全部的 class(JDK 表明 JDK 的安装目录,下同),或被-Xbootclasspath参数指定的路径中的,而且能被虚拟机识别的类库(如 rt.jar,全部的java.*开头的类均被 Bootstrap ClassLoader 加载)。启动类加载器由 C++ 实现,不是 ClassLoader 子类。没法被 Java 程序直接引用的。
②Extension ClassLoader扩展类加载器
该加载器由sun.misc.Launcher
③App ClassLoader应用程序类加载器
。该类加载器由 sun.misc.Launcher$AppClassLoader 来实现,负责记载 classpath 中指定的 jar 包及目录中 class,开发者能够直接使用该类加载器,若是应用程序中没有自定义过本身的类加载器,通常状况下这个就是程序中默认的类加载器。
启动类加载器:它使用 C++ 实现(这里仅限于 Hotspot,也就是 JDK1.5 以后默认的虚拟机,有不少其余的虚拟机是用 Java 语言实现的),是虚拟机自身的一部分。
全部其余的类加载器:这些类加载器都由 Java 语言实现,独立于虚拟机以外,而且所有继承自抽象类 java.lang.ClassLoader,这些类加载器须要由启动类加载器加载到内存中以后才能去加载其余的类。
应用程序都是由这三种类加载器互相配合进行加载的,咱们还能够加入自定义的类加载器。
①加载
加载时类加载过程的第一个阶段,在加载阶段,虚拟机须要完成如下三件事情:
①经过一个类的全限定名来获取其定义的二进制字节流。
②将这个字节流所表明的静态存储结构转化为方法区的运行时数据结构。
③在 Java 堆中生成一个表明这个类的 java.lang.Class 对象,做为对方法区中这些数据的访问入口。
注意,这里第 1 条中的二进制字节流并不仅是单纯地从 Class 文件中获取,好比它还能够从 Jar 包中获取、从网络中获取(最典型的应用即是 Applet)、由其余文件生成(JSP 应用)等。
相对于类加载的其余阶段而言,加载阶段(准确地说,是加载阶段获取类的二进制字节流的动做)是可控性最强的阶段,由于开发人员既可使用系统提供的类加载器来完成加载,也能够自定义本身的类加载器来完成加载。
相对于类加载的其余阶段而言,加载阶段(准确地说,是加载阶段获取类的二进制字节流的动做)是可控性最强的阶段,由于开发人员既可使用系统提供的类加载器来完成加载,也能够自定义本身的类加载器来完成加载。
JVM主要在程序第一次主动使用类的时候,才会去加载该类。也就是说,JVM并非在一开始就把一个程序就全部的类都加载到内存中,而是到用的时候才把它加载进来,并且只加载一次
加载过程当中会先检查类是否被已加载,检查顺序是自底向上,从 Custom ClassLoader 到 BootStrap ClassLoader 逐层检查,只要某个 Classloader 已加载就视为已加载此类,保证此类只全部 ClassLoade r加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
这几种类加载器的层次关系以下图所示:
这种层次关系称为类加载器的双亲委派模型。双亲委派模型的工做流程是:
若是一个类加载器收到了类加载的请求,它首先不会本身去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上 所以,全部的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即没法完成该加载,子加载器才会尝试本身去加载该类。
②链接
①验证
验证的目的是为了确保 Class 文件中的字节流包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。不一样的虚拟机对类验证的实现可能会有所不一样,但大体都会完成如下四个阶段的验证:文件格式的验证、元数据的验证、字节码验证和符号引用验证。
②准备
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有如下几点须要注意:
这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在 Java 堆中。 这里所设置的初始值一般状况下是数据类型默认的零值(如 0、0L、null、false 等),而不是被在 Java 代码中被显式地赋予的地赋予的值。
③解析
解析阶段是虚拟机将常量池中的符号引用转化为直接引用的过程。
解析动做主要针对类或接口、字段、类方法、接口方法四类符号引用进行,分别对应于常量池中的 CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info 四种常量类型。
③初始化
类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的 Java 程序代码。虚拟机规范严格规定了有且只有四种状况必须当即对类进行初始化:
①遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,若是类尚未进行过初始化,则须要先触发其初始化。生成这四条指令最多见的 Java 代码场景是:使用 new 关键字实例化对象时、读取或设置一个类的静态字段(static)时(被 static 修饰又被 final 修饰的,已在编译期把结果放入常量池的静态字段除外)、以及调用一个类的静态方法时。 ②使用 Java.lang.refect 包的方法对类进行反射调用时,若是类尚未进行过初始化,则须要先触发其初始化。 ③当初始化一个类的时候,若是发现其父类尚未进行初始化,则须要先触发其父类的初始化。 ④当虚拟机启动时,用户须要指定一个要执行的主类,虚拟机会先执行该主类
虚拟机规定只有这四种状况才会触发类的初始化,称为对一个类进行主动引用,除此以外全部引用类的方式都不会触发其初始化,称为被动引用
⑤静态加载和动态加载
Java初始化一个类的时候能够用new 操做符来初始化,也可经过Class.forName的方式来获得一个Class类型的实例,而后经过这个Class类型的实例的newInstance来初始化.咱们把前者叫作JAVA的静态加载,把后者叫作动态加载.。
时候咱们说某个语言具备很强的动态性,有时候咱们会区分动态和静态的不一样技术与做法。咱们朗朗上口动态绑定(dynamic binding)、动态连接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而广泛适用的严格定义,有时候甚至像面向对象当初被导入编程领域同样,一人一把号,各吹各的调。
通常而言,开发者社群说到动态语言,大体认同的一个定义是:“程序运行时,容许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
尽管在这样的定义与分类下Java不是动态语言,它却有着一个很是突出的动态相关机制:Reflection。Java程序能够加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
静态加载的时候若是在运行环境中找不到要初始化的类,抛出的是NoClassDefFoundError,它在JAVA的异常体系中是一个Error.
动态态加载的时候若是在运行环境中找不到要初始化的类,抛出的是ClassNotFoundException,它在JAVA的异常体系中是一个checked异常,在写代码的时候就须要catch.
⑥反射
①获取class
②获取构造方法
③获取类的成员方法
④获取类的成员变量(成员属性)
反射机制将另起篇幅学习
⑦程序运行
学习并转载自https://blog.csdn.net/u012585964/article/details/52011138/