Java内存模型概述
Java内存模型(JMM)定义了Java程序中多线程环境下变量的访问规则,确保线程间的数据可见性和有序性。JMM通过主内存和线程工作内存的抽象概念实现,每个线程操作的数据副本存储在工作内存中,最终同步到主内存。
JMM的核心特性包括:
- 原子性:基本数据类型的读写操作是原子的。
- 可见性:
volatile关键字确保变量的修改对所有线程立即可见。 - 有序性:通过
happens-before规则防止指令重排序。
// 示例:volatile保证可见性
public class SharedObject {
private volatile int counter = 0;
public void increment() { counter++; }
}
JVM内存区域划分
JVM内存分为以下几个主要区域:
- 堆(Heap):存储对象实例,是垃圾回收的主要区域。
- 方法区(Method Area):存储类信息、常量、静态变量。
- 虚拟机栈(VM Stack):线程私有,存储局部变量和方法调用栈帧。
- 本地方法栈(Native Method Stack):为Native方法服务。
- 程序计数器(PC Register):记录当前线程执行的位置。
堆内存结构:
- 新生代(Young Generation):包含Eden区和两个Survivor区(S0/S1)。
- 老年代(Old Generation):长期存活的对象晋升至此。
垃圾回收算法
-
标记-清除(Mark-Sweep)
分为标记阶段(识别存活对象)和清除阶段(回收未标记对象)。缺点:产生内存碎片。 -
复制算法(Copying)
将存活对象从Eden区复制到Survivor区。适合新生代回收,如Serial、ParNew收集器。 -
标记-整理(Mark-Compact)
标记后移动存活对象到内存一端,消除碎片。CMS收集器在老年代使用此算法。 -
分代收集(Generational)
结合前三种算法,针对不同代采用最优策略。
垃圾回收器类型
-
Serial收集器
单线程执行GC,简单高效,适用于客户端应用。 -
Parallel Scavenge收集器
多线程并行回收,注重吞吐量,适合后台计算任务。 -
CMS(Concurrent Mark-Sweep)收集器
以最短停顿时间为目标,分为初始标记、并发标记、重新标记、并发清除四阶段。 -
G1(Garbage-First)收集器
将堆划分为多个Region,优先回收垃圾最多的区域,平衡吞吐量与延迟。
内存泄漏与调优
常见内存泄漏场景:
- 静态集合持有对象引用。
- 未关闭的
InputStream或数据库连接。 - 监听器未注销。
调优参数示例:
-Xms和-Xmx:设置堆初始和最大值。-XX:NewRatio:调整新生代与老年代比例。-XX:+UseG1GC:启用G1收集器。
# 示例:启动参数
java -Xms512m -Xmx1024m -XX:+UseG1GC MainClass
监控工具与实战
-
jstat
监控堆内存和GC情况:jstat -gcutil <pid> 1000 -
VisualVM
图形化分析堆转储(Heap Dump),识别内存占用对象。 -
MAT(Memory Analyzer Tool)
分析内存泄漏,生成对象引用链报告。
1万+

被折叠的 条评论
为什么被折叠?



