"jvm内存模型个人笔记"
Java虚拟机(JVM)内存模型是Java运行时数据区域的架构,它负责管理和处理程序的运行时数据。以下是对标题和描述中涉及的知识点的详细说明:
1. **JVM内存模型:**
JVM内存模型主要包含五个基本部分:
- **栈(Stack)**:每个线程都有自己的栈,用于存储局部变量表、操作栈、动态链接和方法出口等信息。每次方法调用时,栈帧会入栈,方法结束时出栈。
- **本地方法栈(Native Method Stack)**:类似于栈,但用于执行本地(Native)方法,即非Java语言编写的代码。
- **程序计数器(Program Counter Register)**:记录当前线程执行的字节码的地址,每个线程都有自己的计数器,执行Native方法时计数器为空。
- **堆(Heap)**:是JVM中最大的一块内存,所有线程共享,用于存储对象实例。堆被分为不同的代,如年轻代(Young Generation)、老年代(Old Generation),以适应不同生命周期的对象。如果堆空间不足,会触发OutOfMemoryError(OOM)异常。
- **方法区(Method Area)**:在Java 8之前称为永久代(Permanent Generation),在Java 8及以后版本称为元空间(Metaspace)。它存储已加载的类信息、常量、静态变量和即时编译后的代码。
2. **垃圾收集(GC):**
- **分代回收**:将堆内存划分为不同年代,如年轻代(包括 Eden 和两个Survivor区)和老年代,使用不同的垃圾收集策略。年轻代通常使用复制算法,老年代常用标记-清除或标记-整理算法。
- **回收器实现**:主要有串行回收器、并行回收器、并发标记扫描(CMS)、G1垃圾收集器和ZGC等。这些回收器有不同的性能特性和适用场景。
3. **类加载机制:**
- **双亲委派模型**:类加载器在加载类时,首先将请求传递给其父类加载器,只有当父类加载器无法加载时,子类加载器才会尝试加载。这种机制防止了类的重复加载,并保护了核心API不受篡改。
- **类加载器层次**:Bootstartp类加载器(最顶级)、Extension类加载器、System类加载器(也称应用类加载器)以及自定义类加载器。
4. **Java内存模型(JMM):**
JMM规定了多线程环境下如何访问共享变量,确保线程安全。它提供了以下保证:
- **原子性(Atomicity)**:通过锁或者CAS操作保证,使得一个操作要么全部完成,要么不开始。
- **可见性(Visibility)**:使用volatile关键字可以确保一个线程对变量的修改对其他线程可见。
- **有序性(Ordering)**:通过内存屏障来限制指令重排序,保证特定的顺序执行。
JMM定义了八种操作来控制主内存和工作内存之间的交互:
- lock(锁定)
- unlock(解锁)
- read(读取)
- load(载入)
- use(使用)
- assign(赋值)
- store(存储)
- write(写入)
这些操作保证了线程间的正确通信和同步,防止出现数据不一致的情况。