JVM内存模型
- 栈:又称方法栈,线程私有的,线程执行方法时都会创建一个栈帧,用来存储局部变量表、操作栈、动态链接、方法出口等信息,调用方法时入栈,方法返回时出栈。
- 本地方法栈:与栈类似也是用来保存方法的信息,但它不是为Java方法服务,而是Native方法(C语言)。
- 程序计数器:保存当前线程执行的字节码位置,作用是当操作系统分配CPU资源,线程切换时每个线程就需要记录下一条要运行的指令位置。
- 堆:存放对象实例和数组,JVM内存管理最大的一块,被线程共享。
- 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量。
线程独占:栈、本地方法栈、程序计数器
线程共享:堆、方法区
垃圾回收机制
堆的空间分配
- 新生代(1/3堆空间)
- Eden区(8/10)
- From区(1/10)
- To区(1/10)
- 老年代(2/3堆空间)
Eden区是Java新对象的出生地,From区保存上一次GC的幸存者。不过大对象直接进入老年代,避免大量的内存拷贝。
GC分为两种,新生代用的叫MinorGC,老年代的用叫MajorGC。
- MinorGC采用的算法:复制算法
- MajorGC采用的算法:标记-清除算法
- MinorGC 和 MajorGC 一起叫 FullGC
复制算法:
首先,把Eden区和From区中存活的对象复制到To区,同时把这些对象的年龄+1,如果有对象的年龄到达了老年的标准则复制到老年区。
然后,清空Eden区和From区中的对象。
最后,To区和From区互换(原To区成为下一次GC时的From区)。
标记-清除算法:
标记阶段标记出所有需要回收的对象,然后将存活对象移到一端,剩下的全部清除,避免了内存碎片化。