(JVM调优实战篇 一) JVM基础知识概览
目录
四、运行时数据区 (Run-Time Data Areas)
一、JDK8 概览
JDK ---> JRE ----> JVM
我们平常开发中常用到的是JAVASE相关的API,进行业务开发,但是我们对JAVA的其余相关关注并不是太高,就比如,当我们编辑好JAVA文件,当文件通过JAVAC被编译成为 .class 文件之后的事情,我们并不是太关心,本文今天以JAVA---->JAVAC---->JVM一步一步的进行分析。
二、编译分析
当JAVA文件被JAVAC编译的时候,编译器做了些什么事情呢?
javac编译器 : 词法分析--->语法分析--->语法书--->字节码生成器---> .class文件 (JVM运行文件)
被编译成.class文件之后,就要通过类加载机制使得类文件到达JVM虚拟机。
类加载机制 class ---> 类加载机制 ---> JVM
- 加载
- 先找到类文件所在位置
- 类文件的信息交给JVM ----> method area【方法区】
- 类文件所对应的Class对象 ----> Heap【堆】
- 链接
- 验证【正确性】
保证被加载的类的正确性
- 准备
- 为类的静态变量分配内存空间并将其的值初始化默认值
- 举个例子,比如我们定义了一个静态变量 int a = 10; 现在就是定义变量,并将其附上默认值 0 ;
- 为类的静态变量分配内存空间并将其的值初始化默认值
- 解析
- 将类中的 符号引用 转换为 直接引用
- 字节码文件中的符号代称转化为内存中真实存在的内存地址
- String str = "xxxx"; 将编译的符号引用 0_xxx 类似,转换为内存中真实存在的内存地址
- 字节码文件中的符号代称转化为内存中真实存在的内存地址
- 将类中的 符号引用 转换为 直接引用
- 初始化
为静态变量初始化值, int a = 10;
三、类加载机制图解(了解即可)
类加载机制,最主要的就是类加载器,Java也将类加载器进行了合理的分类,各司其职。
类加载器 ClassLoader
- 分类
1)Bootstrap ClassLoader 负责加载$JAVA_HOME中 jre/lib/rt.jar 里所有的class或 Xbootclassoath选项指定的jar包。由C++实现,不是ClassLoader子类。
2)Extension ClassLoader 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中 jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。
3)App ClassLoader 负责加载classpath中指定的jar包及 Djava.class.path 所指定目录下的类和 jar包。
4)Custom ClassLoader 通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根据 自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。
- 图解
- 加载规则
检查某个类是否已经加载:
顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检 查,只要某个Classloader已加载,就视为已加载此类,保证此类只所有ClassLoader加载一次。
加载的顺序:
加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
双亲委派机制 :
定义:如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把 这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就 成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
优势:Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如,Java中的 Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型 最顶端的启动类加载器进行加载,因此Object在各种类加载环境中都是同一个类。如果不采用 双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object 类。
破坏:可以继承ClassLoader类,然后重写其中的loadClass方法。