JAVA内存模型
- 方法区 (已加载的类信息、常量、静态变量)
- 堆(对象、数组)
- 虚拟栈 (局部变量、操作数栈)
- pc计数器
- 本地方法栈 (native)
堆和方法区是共享,其他线程私有
对象的创建
- 检查类是否已被加载
- 分配对象
- 填充对象头
对象的内存布局
- 对象头
- 实例数据
- 对齐填充
对象的访问定位
- 句柄池访问
- 直接指针访问
垃圾回收
如何判断对象是否死亡
- 引用计数法
- 难以解决互相引用
- 可达性分析
引用分类
- 强
- 弱(内存不够,才回收)
- 软
- 虚
垃圾回收算法
- 标记清除 (被引用了 就+1 没有就清除,但开销大 效率低)
- 复制算法 (一分为二,将存活的复制到另一块上)
- 分代回收 (一分为二太奢侈、新生代 8:1:1 Eden From to | 老年代)
堆内存分配
- young gc快
- 大对象、长期存活 进入old
JAVA内存和线程
线程和内存交互关系
- 只有lock unlock read 直接作用于主内存
- 其他都是作用于工作内存再刷写到主内存
volatile
- 可见
- 非原子操作
- 禁止指令重排
并发特性
- 原子
- 可见
- 有序
JAVA线程调度
- 协同式
- 抢占式
JAVA五种状态
类加载
类加载流程
- 加载 (通过类的全限定名来读取类的二字节流、静态数据转化为方法区的数据结构、生成一个class对象作为调用入口)
- 验证
- 文件格式 (cafebabe 版本号等)
- 元数据验证 (java语言规范 类相关)
- 字节码验证
双亲委派模型
如果一个加载类收到类加载请求,则会将请求委派给父类加载器去执行,如果父类不能加载,子类才会尝试加载。
为什么这样做: 防止类重复加载,