Java中99%的对象放在堆中,堆是垃圾回收主要操作区域。
新生代分为eden区,survivor1和survivor2区 比例是8:1:1
新生代的对象在经过15次GC之后进入老年代,大对象直接进入老年代。
绝大多数最新被创建的对象会分配到新生代,大部分对象在创建之后很快变得不可达,所以很多对象被创建在新生代,然后消失。对象从这个区域消失的过程我们称之为 minor GC。
老年代
对象没有变得不可达,并且从新生代中存活下来,会被拷贝到这里。其所占用的空间要比新生代多。也正由于其相对较大的空间,发生在老年代上的GC要比新生代要少得多。对象从老年代中消失的过程,可以称之为major GC(或者full GC)。
永久代
垃圾回收机制
JVM垃圾回收机制
https://www.bilibili.com/video/BV1pZ4y197KK?p=9&spm_id_from=pageDriver
JVM内存中线程共享的是堆和本地方法区,
线程私有的是栈和程序计数器 栈又分为本地方法栈和虚拟机栈
GC
minorGC
minorgc 发生在年轻代
majorgc发生在老年代
JVM年轻代分为三个区域
- Eden
- Survivor(from)
- Survivor(to)
Eden和两个Survivor区 默认比例 8:1:1
为什么要分Eden和Survivor区,
因为新生代发生的gc比较频繁,如果不分Survivor区,那么Eden发生gc后 存活的对象直接被送到老年代,老年代会很快被填满. 而发生在老年代的Fgc消耗的时间要比ygc长的多.
设置两个Survivor区最大的好处就是减少了内存的碎片化
年轻代里的minorgc发生的特别频繁
新产生的对象大部分都放在Eden区
新建的对象都放在Eden区中,
第一次ygc
Eden区的大部分都会被回收 ->s0
第二次ygc
Eden区的和s0活着的对象->s1
第三次ygc
Eden区和s1活着的对象->s0
…
…
每次换区(s0->s1/s1->s0)
对象的年龄都会+1
多次垃圾回收后, 当对象的年龄到了,就会被放到老年代(Old区)
再后来, 老年代满了之后 会出发FullGC
对象分配规则
大对象直接分配到老年代,避免Eden区和Survivor区大量的内存拷贝
(动态年龄判断)
当Survivor区相同年龄的所有对象加起来大于Survivor区的一半 那么大于等于这个年龄的对象可以进入老年代
垃圾回收器
针对年轻代
- Serial 最基本的,发展历史最悠久的收集器工作环境是单线程, 收集器进行垃圾回收的时候,必须暂停其他所有的工作线程 (Stop The World)
几十M /几M内存用Serial完全没问题如果内存很大, STW时间会特别长 - Parallel Scavenge
并行清理垃圾(多线程) 并不是线程数越高效率越高 ,线程的上下文切换比较消耗资源
并行收集::指多个垃圾回收器同时收集垃圾,此时业务逻辑线程暂停工作 - ParNew收集器 Serial收集器的多线程版本, 需要STW,使用的是复制算法
- CMS (concurrent mark sweep)
并发垃圾回收用的是标记清除算法,会产生内存碎片
这款收集器第一次实现了让垃圾收集线程与用户线程同时工作.
CMS的关注点是尽可能缩短垃圾回收时,用户线程的停顿时间.停顿时间越短,越适合与用户交互的系统.
JDK1.8以上 CMS建议升级为G1 - Serial Old收集器是Serial收集器的老年代版本, 主要针对老年代,
- Parallel Old收集器: 是Parallel Scavenge收集器的老年代版本,使用多线程,标记-整理算法。
常用垃圾回收算法
标记清除算法
标记到的垃圾可以直接回收,缺点就是内存碎片化,浪费空间
这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放。
缺点
需要扫描两遍,效率较低
GC的时候需要停止整个应用程序,用户体验感较差
这种方式清理出来的空闲内存是不连续的,产生内存碎片。需要维护一个空闲列表
拷贝算法(用在年轻代)
把一片内存分成大小相等的两块,每次只使用其中的一块,
当这一块的内存用完了,就把存活的对象复制到另外一块上面,然后把已使用的内存一次清理掉
优点是 保证了内存的连续可用
缺点是比较浪费空间(内存只能使用一半) 代价较高.
标记压缩
比标记清除多了一步整理,解决碎片化问题
整理压缩阶段,不是对标记的对象回收, 而是将存活的对象都向一端移动,然后擦除边界以外的内存
可以看到,标记的存活对象将会被整理,按照内存地址一次排列,而被标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比维护一个空闲列表少开销多了