码迷,mamicode.com
首页 > 其他好文 > 详细

HotSpot JVM学习

时间:2021-05-24 02:37:26      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:最可   lin   java   默认   lazy   机制   cat   返回   tar   

技术图片

类加载

技术图片

加载过程

1.加载Loading

  1. 通过一个类的全限名获取此类的二进制字节流
  2. 将字节流所代表的静态存储结构转化为方法区(1.8为元空间实现,1.8前永久代)的运行时数据结构
  3. 在内存中生成代表该类的java.lang.Class对象,作为方法区这个类的访问人口

2.连接Linking

2.2验证

  • 确保Class文件的字节流中的信息符合虚拟机规范,保证加载类的正确性,不会危害虚拟机的自身安全。
  • 验证阶段大致四个动作:文件格式验证、元数据验证、字节码验证、符号引用验证

2.3准备

  • 为类变量(static)分配内存并设置默认初始值。
  • final修饰的类变量在编译时分配,准备阶段显式初始化。

2.4解析

将常量池内的符号引用转化为直接引用

3.初始化Initialization

  • 初始化阶段就是执行类构造器方法<clinit>()的过程,<clinit>()是编译器自动收集所有类变量的赋值动作和静态代码块中的语句合并生成。
  • 编译器收集顺序按源文件顺序决定。
  • <clinit>()不同于类的构造器(构造器对应虚拟机视角下的<init>()),若该类有父类,父类<clinit>()方法会在子类的<clinit>()方法前调用。
  • 虚拟机保证在一个类的<clinit>()方法在多线程下被同步加锁,保证一个类只被加载一次。

类加载器

技术图片

启动类加载器Bootstrap classLoader

顶层类加载器底层C++实现,主要加载<JAVA_HOME>\lib目录下且被JVM能识别的类库至内存

扩展类加载器ExtClassLoader

主要负责加载<JAVA_HOME>\lib\ext目录下的一些扩展的jar,开发者可直接使用的加载器。

技术图片
使用ExtClassLoader.getParent得到的加载器为null?是否说ExtClassLoader的父类加载器为null?

public abstract class ClassLoader {
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (lock) {
           ...
            if (target == null) {
                try {
                    if (parent != null) {
                        target = parent.loadClass(name, false);
                    } else {
                        // 所有父类加载器为null的加载器,其父类都为启动类加载器BootstrapClassloader
                        target = findBootstrapClassOrNull(name); 
                    }
                } catch (ClassNotFoundException e) {...}
            ...
        }
    }
private Class<?> findBootstrapClassOrNull(String name){
    if (!checkName(name)) return null;
    return findBootstrapClass(name);
}
private native Class<?> findBootstrapClass(String name);// native方法,通过JNI调用底层C

应用程序类加载器APPClassLoader

主要负责加载用户类路径(ClassPath)下的所有类库,父类加载器为ExtClassLoader。

  • 自定义类加载器默认使用ApplicationClassLoader进行加载,系统核心类库都是使用引导类加载器进行加载
  • ClassLoader只负责类的加载,执行引擎(Execution Engine)决定是否可运行

双亲委派机制

Java虚拟机对class文件采用按需引入,即需要使用该类时才会将他的class文件加载到内存生成class对象。

工作原理

  1. 当一个类加载器收到了类加载的请求时,不会自己去加载,而是把请求交给父类的加载器去执行。
  2. 如果父类加载器还有父类加载器时,进一步向上委托,依次递归,请求最终到达启动类加载器。
  3. 如果父类记载器可以完成类加载,超过返回。若父类无法完成加载,子类才会尝试加载。

为什么需要双亲委派

确保类的全局唯一性通过双亲委托机制,Java虚拟机总是先从最可信的Java核心API查找类型,可以防止不可信的类假扮被信任的类对系统造成危害。
技术图片

JMM

技术图片

虚拟机栈VM Stack

线程私有,生命周期与线程相同,每个方法执行时同步创建一个栈帧(Stack Frame),栈帧存储了方法的存储局部变量表、操作栈、动态链接、返回地址等信息
技术图片

堆Heap

线程共享,在虚拟机启动时创建。存储对象实例及数组,GC的主要作用区域。

GC

新生代

老年代

方法区

线程共享内存区域,存储已被虚拟机加载的类型信息、常量、静态变量、运行时常量池

HotSpot JVM学习

标签:最可   lin   java   默认   lazy   机制   cat   返回   tar   

原文地址:https://www.cnblogs.com/heyufeng0313/p/14747004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!