JAVA内存模型

  • 方法区 (已加载的类信息、常量、静态变量)
  • 堆(对象、数组)
  • 虚拟栈 (局部变量、操作数栈)
  • pc计数器
  • 本地方法栈 (native)

堆和方法区是共享,其他线程私有

对象的创建

  • 检查类是否已被加载
  • 分配对象
  • 填充对象头

对象的内存布局

  • 对象头
  • 实例数据
  • 对齐填充

对象的访问定位

  • 句柄池访问
  • 直接指针访问

垃圾回收

如何判断对象是否死亡

  • 引用计数法
    • 难以解决互相引用
  • 可达性分析

引用分类

  • 弱(内存不够,才回收)

垃圾回收算法

  • 标记清除 (被引用了 就+1 没有就清除,但开销大 效率低)
  • 复制算法 (一分为二,将存活的复制到另一块上)
  • 分代回收 (一分为二太奢侈、新生代 8:1:1 Eden From to | 老年代)

堆内存分配

image.png

  • young gc快
  • 大对象、长期存活 进入old

JAVA内存和线程

线程和内存交互关系

image.png

  • 只有lock unlock read 直接作用于主内存
  • 其他都是作用于工作内存再刷写到主内存

volatile

  • 可见
  • 非原子操作
  • 禁止指令重排

并发特性

  • 原子
  • 可见
  • 有序

JAVA线程调度

  • 协同式
  • 抢占式

JAVA五种状态

image.png

类加载

类加载流程

image.png

  • 加载 (通过类的全限定名来读取类的二字节流、静态数据转化为方法区的数据结构、生成一个class对象作为调用入口)
  • 验证
    • 文件格式 (cafebabe 版本号等)
    • 元数据验证 (java语言规范 类相关)
    • 字节码验证

双亲委派模型

image.png

如果一个加载类收到类加载请求,则会将请求委派给父类加载器去执行,如果父类不能加载,子类才会尝试加载。

为什么这样做: 防止类重复加载,