Java跨平台的语言
Java是一门面向对象编程语言,不仅吸收了C++语言的各种有点,还摒弃了C++里难以理解的多继承、指针等概念;因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的 代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
一次编译,到处运行。

JVM与JAVA关系
Java是一门计算机编程语言
Jvm是一个跨平台的运行环境
Java生成的字节码可以在JVM平台上运行
JVM可以理解为Java的底层原理实现。

java运行流程

JVM运行架构

JVM:
类加载子系统---->运行时数据区--->理解两个对象--->执行引擎+GC--->监控与参数--->高级案例
类加载子系统---->程序计数器--->虚拟机栈--->本地方法栈--->Heap堆--->方法区--->String对象
--->Object对象--->执行引擎--->垃圾回收--->监控命令--->图形监控--->GC日志--->运行参数
--->常见故障--->性能调优--->真实案例--->生态优化

JVM类加载流程
class字节码

javap -c demo.class
Compiled from "demo.java" public class demo { static int a; public demo(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(); Code: 0: return static {}; Code: 0: iconst_1 1: putstatic #7 // Field a:I 4: return }
class与字节码
(a) class文件是一种字节码体现形式,但字节码不局限于class文件,它本质是一段二进制流,可以以其它形式存在;
(b)字节码是一种通用的、与平台无关的存储格式。理论上任何编程语言,只要能被编译成字节码,就可以交付给JVM去跨平台的运行
(c)Java语言在诞生之初喊出的口号"write once,Run anywhere",正是基于字节码(byte code)设计,java能够做到平台无关性,字节码功不可没
(d)从结构角度上讲,class字节码包括了魔幻数、版本好、常量池等信息
魔幻数: 0xCAFEBABE
版本信息:class文件的次要版本和主要版本
Constant Pool:类的常量池
Access Flags:例如类是否为抽象类、静态类等
This class: 当前类的名称
Super Class: 超类的名称
Interfaces:类中的任何接口
Fields: 类中的任何字段
Methods: 类中的任何方法
Attributes:类的任何属性
类加载子系统:
|-------------------------------|-------------|
| 加载阶段Loading | 链接阶段Linking |
| 引导类加载 BootStrap ClassLoader | 验证 Verify |
| 扩展类加载 ExtenSion ClassLoader | 准备 Prepare |
| 应用类加载 Application ClassLoader | 解析 Resolve |
类加载器是将字节码文件转换为JVM内存Class对象的工具
(1) 类在使用之前,首先要调用类加载子系统进行加载
(2)类加载子系统负责从文件或者网络中加载字节码文件
(3)类加载的过程是按照二进制流的方式进行加载,并且遵循class字节码规范
(4)类加载子系统只负责确保类的正确加载,是否允许,则由执行引擎决定
(5)加载的类信息存放于方法区,除了类信息外,字节码中的常量池,会加载至方法区,形成运行时常量池。
类加载流程:
class文件-->加载-->验证-->准备-->解析-->初始化-->卸载
加载:通过类全名获取类二进制流,并将静态的存储结构,加载到运行时数据区中的方法区(生成class类对象),加载的来源常见有本地文件,网络流,压缩包,动态代理等等。
验证:确保class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全,主要包括四种验证,文件格式验证,元数据验证,字节码验证,符合引用验证。
准备:为static变量/类变量分配内存(方法区),并且设置该变量的初始值为(不包括final和实例变量)
解析:主要是将常量池中的符号引用替换为直接引用,比如类、接口、方法、字段等等。
初始化:真正执行初始化类阶段;若该类具有超类,先对超类进行初始化,在单个类内部,初始化包括:类变量/静态初成员初始化,初始化代码块,静态构造函数初始化。
双亲委派机制

(1)当一个类加载器收到了类加载的请求的时候,他不会直接区加载指定的类,而是把这个请求委托给自己的父加载器去加载;
(2)如果父类加载器,还存在父类加载器,则进一步向上委托,直到引导类加载器;
(3)如果父类加载器,可以完成加载,则因为加载完成,否则,则反向采用子类依次加载,直到成功;
(4)父类加载器永远优先于子类加载器加载。
双亲委派的优势:
(1)避免类的重复加载,确保一个类的全局唯一性
(2)Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子classloader再加载一次
(3)保护程序安全,防止核心API被随意篡改。
弊端:
检查类是否加载的委托过程是单向的,这个方式虽然从结构上说比较清晰,使各个classLoader的职责非常明确,但是同时会带来一个问题,即顶层的classloader无法访问底层的classloader所加载的类。
如何破坏:
(1)双亲委派的核心实现在classloader中的loadclass(String name, boolean resolve)
(2)自定义一个类加载器,重写其中的loadclass方法,使其不进行双亲委派即可。