JVM内存结构与GC
前段时间没有好好准备,错过了“金三银四”,因此最近开始恶补各方面知识,决定先从jvm内存结构和gc开始。
jvm内存结构分为如下几部分(前两项为线程共享,后三项为线程私有的):
1、方法区:存储已经被虚拟机加载的类信息、常量、jit(及时编译器just in time)编译后的代码以及类变量(static修饰的变量)。
2、堆内存:jvm中最大的内存区域,java运行时创建的所有对象几乎都存在于此,并且还是gc的重点照顾区域,除此之外还存0有实例变量。
3、虚拟机栈:生命周期与线程相同,方法执行时创建栈帧这种数据结构,存放局部变量表、操作站、动态链接、方法出口等信息。栈帧的大小代表虚拟机栈的宽度,数量代表深度。
4、本地方法栈:调用本地方法的接口(jni),网络通信、文件操作的底层。
5、程序计数器:存放当前线程接下来将要执行的字节码指令,分支、循环、跳转、异常处理等信息。
垃圾回收部分:
hotspot vm分为了年轻代(young)、老年代(tenured)和永久区(perm)。年轻代又被分为1个eden区和两个survivor区(分别叫from和to),其中eden是对象的出生地,每经历一次gc并且存活下来则“年龄”增长一岁,进行至少一次gc并且存活下来后进入survivor区,而若到了指定的年龄(默认是15岁)仍未回收,则有机会进入老年代。
回收算法:
1、标记 — 清除算法:分为两阶段:第一阶段先从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。需要暂停整个应用,但是会产生内存碎片。
2、复制算法:将内存分为两个区域,使用的只有其中一个区域,当进行垃圾回收时,遍历正在使用的区域,直接将所有存活对象复制到未使用的区域中,因此是进行垃圾回收的同时也进行了内存整理,不会出现内存碎片问题。
3、标记 — 整理算法:此算法结合了以上两种算法,也是分为两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,消除未标记对象并且把存活对象“压缩”到堆的一头,按顺序排放,避免了标记 — 清除算法的碎片问题,同时也避免了复制算法的空间问题。