JVM内存模型与垃圾回收
本篇就总结性的描述下JVM的内存模型与垃圾回收相关的知识。
内存模型
各部分的功能
栈里面存放的是基本的数据类型和引用,而堆里面则是存放各种对象实例的。
栈区
线程私有,生命周期与线程相同。每个方法执行的时候都会创建一个栈帧(stack frame)用于存放 局部变量表、操作栈、动态链接、方法出口。
栈存储了处理逻辑。栈保存了上下文的信息,因此只能向上增长
堆
存放对象实例,所有的对象的内存都在这里分配。垃圾回收主要就是作用于这里的。
堆存储了具体的数据,堆是动态分配。
程序计数器
这里记录了线程执行的字节码的行号,在分支、循环、跳转、异常、线程恢复等都依赖这个计数器。
方法区
类型信息、字段信息、方法信息、其他信息
总结
名称 | 特征 | 作用 | 配置 | 异常 |
---|---|---|---|---|
栈区 | 线程私有,使用一段连续的内存空间 | 存放局部变量表、操作栈、动态链接、方法出口 | -XSs | StackOverflowError OutOfMemoryError |
堆 | 线程共享,生命周期与虚拟机相同 | 保存对象实例 | -Xms -Xmx -Xmn | OutOfMemoryError |
程序计数器 | 线程私有、占用内存小 | 字节码行号 | 无 | 无 |
方法区 | 线程共享 | 存储类加载信息、常量、静态变量等 | -XX:PermSize -XX:MaxPermSize | OutOfMemoryError |
垃圾回收
可达性分析判断对象可以回收的情况:
- 显示的把某个引用置位NULL或者指向别的对象
- 局部引用指向的对象
- 弱引用关联的对象
垃圾回收的方法
Mark-Sweep标记-清除算法
这种方法优点就是减少停顿时间,但是缺点是会造成内存碎片。
Copying复制算法
这种方法不涉及到对象的删除,只是把可用的对象从一个地方拷贝到另一个地方,因此适合大量对象回收的场景,比如新生代的回收。
Mark-Compact标记-整理算法
这种方法可以解决内存碎片问题,但是会增加停顿时间。
Generational Collection 分代收集
把JVM分成不同的区域。每种区域使用不同的垃圾回收方法。总结
名称 | 特征 | 回收算法 | 优缺点 | |
---|---|---|---|---|
新生代(Young Generation) | 用于存放新创建的对象,采用复制回收方法 |
minor GC 如果在s0和s1之间复制一定次数后,转移到年老代中。这里的垃圾回收叫做; |
这种方法不涉及到对象的删除,只是把可用的对象从一个地方拷贝到另一个地方,因此适合大量对象回收的场景,比如新生代的回收。 |
|
年老代(Old Generation) | 这些对象垃圾回收的频率较低,采用的标记整理方法 | 这里的垃圾回收叫做 major GC | 这种方法可以解决内存碎片问题,但是会增加停顿时间。 | |
永久代(Permanent Generation) | 存放Java本身的一些数据,当类不再使用时,也会被回收 | 标记-清除算法 |
这种方法优点就是减少停顿时间,但是缺点是会造成内存碎片。 | |