首页 > 技术文章 > 类加载和内存区域划分

wasitututu 2020-09-15 14:30 原文

jvm什么时候会加载一个类?

  • 代码中用到这个类的时候
    • new对象的时候
    • 加载子类,首先要加载父类

类加载过程

  • 加载 外部的 .class 文件,加载到 Java 的方法区内(内存)
  • 链接
    • 验证 验证字节码是否符合规范
    • 准备 静态变量分配内存并且设置默认值
    • 解析 符号引用替换为直接引用
  • 初始化 类变量赋值,执行静态代码块

类里面都有什么?

  • 静态变量
  • 静态代码块
  • 静态方法
  • 构造方法
  • 实例变量
  • 实例方法
    • 局部变量

类加载器

  • 启动类加载器 lib/rt.jar
  • 扩展类加载器 lib/ext/*.jar
  • 应用类加载器 classpath目录下的类 (classpath =>WEB-INF/classes目录下)

加载机制-双亲委派机制

  • 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父加载器去执行,如果父载器还存在其父加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载
  • 好处
    • 防止核心库被篡改
    • 避免类的重复加载:当父ClassLoader已经加载了该类的时候,就不需要子ClassLoader再加载一次
  • Tomcat打破了双亲委派机制
    • Tomcat自定义了Common、Catalina、Shared等类加载器,加载Tomcat自己的一些核心基础类库
    • Tomcat为每个部署在里面的Web应用都有一个对应的WebApp类加载器,负责加载我们部署的这个Web应用的类

jvm内存区域划分

  • 私有
    • 程序计数器
      • 记录当前执行的字节码指令的行号
    • 虚拟机栈
      • 一个虚拟机栈对应一个线程,和线程的生命周期相同
      • 入栈出栈的过程对应方法的执行过程
        • 一个方法对应一个栈帧,一个方法执行的时候,压入一个栈帧,这个方法执行完,栈帧出栈
        • 所有的字节码指令,都会抽象成对栈的入栈出栈操作
      • 栈帧 对应着方法
        • 局部变量表
        • 操作数栈 对应着方法的执行
        • 动态连接
        • 返回地址
    • 本地方法栈
      • 和虚拟机栈功能类似
  • 公共
    • 方法区
      • 1.8之前,用永久代来实现方法区;1.8之后,用元空间来实现方法区。永久代和元空间都是方法区的实现,方法区是标准,永久代/元空间是实现
      • 存放类信息
      • 存放对象

整体流程图



本文参考救火队长jvm专栏

推荐阅读