title: JVM学习笔记——GC概述
date: 2018/9/2 12:05:00
description: 最近开始着手JVM的学习,在这里把本身学习过程当中的笔记分享出来,但愿能帮到一些小伙伴,同时也是对本身的学习的一个梳理。java
其实GC主要就是思考如下三件事情:算法
a.instance = b; b.instance = a;
使用GC Roots做为起始点,当一个对象到GC Roots没有引用链路时(即不可达),则此时对象视为“死亡”。此方法也是现有JVM中经常使用的算法。
GC Roots包括下面几种:学习
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 本地方法栈中Native方法引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
换句话来讲,以上4中类型其实就是:类成员变量,类静态变量,常量,局部变量,只要某个对象不被以上4种类型关联到,那么该对象就是“已死”的,gc时就会被回收内存空间。指针
针对标记-清除的效率问题,复制算法将内存分为两块空间,每次只使用其中一块。当这块的内存空间用完时,将存活的对象移到另外一块中,而后将已使用的内存空间一次性清理掉。这样作的好处是不会产生碎片,清除也是针对连续的空间作处理,只要移动堆指针就行。
实际上在如今的虚拟机中,将这种算法应用在新生代。按照8:1:1的比例将内存分为三块,每次使用一块较大的与较小的其中一块,清理时将存活对象移到剩下的一块中,这样每次只会浪费10%的内存,因为新生代中的内存通常都是“朝生夕死”的,使用这种算法能够极大的提高效率。可是,不能保证每次清理时,剩下的一块空间可以存放全部的存活对象,因此这里会依赖其余内存空间(通常指老年代)进行分配担保(Handle Promotion)。code
复制算法在对象存活率较高时,效率就会变低,因此针对高对象存活率的状况,就有人提出了该算法。标记的过程并无变化,但标记后并非进行“清除”,而是将存活的对象向一端进行移动整理,而后清除掉其他的空间。现代虚拟机常将这种算法在老年代中使用。对象
分代收集算法是根据对象的存活时间,将内存划分几块(通常分为新生代和老年代),这样就能够根据不一样的内存区域特色采用不一样的算法。针对新生代,使用复制算法,用少许的内存空间换来更大的效率;针对老年代,使用标记-整理或标记-清除来处理。ip