2026-10-30 12:07:25
JVM内存模型是Java虚拟机运行时数据区域的划分及管理机制,主要分为运行时数据区(线程共享)和线程私有数据区,同时包含垃圾收集机制和Java内存模型(JMM)的线程同步规则。以下是详细说明:
一、运行时数据区(线程共享)方法区(Method Area)
功能:存储类信息(如类名、字段、方法)、常量、静态变量、即时编译器(JIT)编译后的代码。
特点:
JDK 1.8前称为永久代(PermGen),使用JVM堆内存;JDK 1.8及以后改为元空间(Metaspace),使用直接内存(堆外内存),避免永久代内存溢出问题。
线程共享,生命周期与JVM一致。
堆(Heap)
功能:存储所有Java对象实例和数组,是垃圾收集器(GC)的主要管理区域。
特点:
线程共享,通过分代算法优化GC效率。
分代结构:
新生代(Young Generation):存放新创建的对象,分为Eden区和两个Survivor区(S0、S1)。
老年代(Old Generation):存放长期存活的对象(如经过多次GC后仍存活的对象)。
程序计数器(Program Counter Register)
功能:记录当前线程执行的字节码指令地址(或native方法地址)。
特点:
线程私有,唯一不会发生内存溢出的区域。
支持线程切换时恢复执行状态。
虚拟机栈(Java Virtual Machine Stack)
功能:存储方法执行的局部变量表、操作数栈、动态链接、方法出口等信息。
特点:
线程私有,方法调用时创建栈帧(Stack Frame),方法结束时栈帧出栈。
可能抛出StackOverflowError(栈深度过大)或OutOfMemoryError(栈扩展失败)。
本地方法栈(Native Method Stack)
功能:为native方法(如C/C++代码)提供服务,存储执行环境。
特点:与虚拟机栈类似,但服务于native方法。
标记-清除算法:标记无用对象后直接清除,可能产生内存碎片。
复制算法:将存活对象复制到另一块内存,适用于新生代(如Eden到Survivor区)。
标记-整理算法:标记后整理存活对象至一端,避免碎片,适用于老年代。
分代算法:结合上述算法,针对不同代采用不同策略。
程序次序规则:单线程内代码按书写顺序执行(不跨线程保证)。
锁规则:解锁操作先于后续对同一锁的加锁操作(如synchronized块)。
Volatile变量规则:对volatile变量的写操作先于后续读操作(保证可见性)。
传递性:若A→B且B→C,则A→C。
线程启动规则:调用start()方法先于线程内任何操作。
线程终止规则:线程内所有操作先于其他线程检测到其终止(如join())。
线程中断规则:interrupt()调用先于被中断线程检测到中断事件。
对象终结规则:构造函数执行结束先于finalize()方法开始。
JVM内存模型通过划分不同区域(如堆、方法区、虚拟机栈等)实现内存的高效管理,垃圾收集机制自动化回收内存,而JMM的Happens-Before规则确保多线程环境下的操作顺序和可见性。理解这些机制有助于优化程序性能、避免内存泄漏和线程安全问题。