提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、垃圾回收-判断垃圾
- 二、垃圾回收-5种引用
- 三、垃圾回收-引用队列
- 四、垃圾回收-软引用弱引用实例
- 五、垃圾回收-回收算法
- 六、垃圾回收-三种垃圾回收器(这一节有点难)
- 七、垃圾回收-新的垃圾回收器G1
- 八、垃圾回收-GC调优
- 总结
前言
一、垃圾回收-判断垃圾
1)引用计数,存在相互调用从而不能被回收的可能,使用没有使用
2)可达分析,根目录不能被回收,如果一个目录能在根目录下找到,那么他不可回收,如果找不到,那么可能是可以被回收
二、垃圾回收-5种引用
强引用----没有强引用时会被垃圾回收
软引用----没有强引用只有软引用时,只有在发生垃圾回收且内存不够的时候才会被垃圾回收
弱引用----没有强引用只有弱引用时,发生垃圾回收就会被回收
虚引用----没有强引用只有虚引用时,会进入引用队列,调用Cleaner中的freeMemery进行垃圾回收(分配直接内存)
终结器引用----没有强引用只有终结器引用时,会进入引用队列,由一个低优先级的线程调用finalize方法,然后就可以被回收
三、垃圾回收-引用队列
如果创建了引用队列,回收后软引用和弱引用会进入引用队列
虚引用和终结器引用则必须需要引用队列,先进入引用队列然后等待回收
四、垃圾回收-软引用弱引用实例
new SoftReference<>(new byte[1024])
发生一次垃圾回收,一次full垃圾回收,一次allocate垃圾回收,最终清除软引用
new ReferenceQueue<>()
软引用会自动入队
new WeakReference<>()
弱引用
五、垃圾回收-回收算法
标记清除--标记后加入可用地址,但是碰到大数组会内存溢出(大连续内存空间),会有内存碎片
标记整理--标记后整理内存碎片,将使用的内存变得连续,比较慢
复制算法--分为两块大小相当的内存空间,from记录to空,将from垃圾回收后,复制到to,形成连续的空间,然后交换from和to的地址,to永远是空着的,缺点是需要双倍的空间
分代回收(复合多种回收算法)

新生代放使用次数不多的,老年代放长久使用的,当新生代数据幸存15次后,会加入老年代
六、垃圾回收-三种垃圾回收器(这一节有点难)
串行

单次时间优先(响应时间优先)

concurrent是并发的,parallel是并行的,前面可以同时执行,后面按顺序单个执行
UserConcMark是作用于老年代的标记清除型,UseParNewGC是作用于新生代的复制型,当UserConcMark出现故障时,会退化成串行的SerialOld,那么什么时候退化呢?
在新生代内存碎片特别多的时候,老年代内存空间也不够,新的内存无法放入新生代,也无法直接放入老年代(特殊),这个时候就会退化成串行的,回收时长会非常长
初始标记受第二个参数的影响,Parallel和下面的一样是并行CPU的个数,4核就是4个。Conc是并发的时候cpu核个数,一般推荐4核用一个进行垃圾回收,其他三个继续执行线程
对吞吐量的影响:并发标记需要占用cpu核,影响程序效率
倒数第二行的参数:进行垃圾回收时还会产生新垃圾,需要CMS预留一些空间等到下次垃圾回收删除。这个值是设置,到了老年代n%时就进行下一次垃圾回收
最后一行的参数:在重新标记时,新生代有可能引用老年代,导致GC要扫描堆和老年代,设置这个参数可以在扫描前就进行一次新生代GC,节约时间。
一次吞吐占用时间优先(吞吐量优先)

最后一个参数是并行的线程,第二个参数会动态调整伊甸园和两个分区和堆的大小
蓝色的两个是目标,第一个是1/(1+ratio),即100分钟只能有几个分钟暂停进行标记
第二个是最大暂停毫秒数,和第一个目标是冲突的,堆大则总时间短但单次时长,反之亦然。
七、垃圾回收-新的垃圾回收器G1
在1.9被设置成了默认的垃圾回收器,1.9之前需要手动开启,取代了CMS
是并发的,同时注重吞吐量和低延迟

重新标记阶段:
一个属性被标记成了白色,等待垃圾回收,因为是并发的,他又被根目录引用了,这个时候如果直接被回收是很大的问题,所以,在被重新引用时会给他加一个写屏障,有了写屏障会被入队并暂时标记成灰色,直到后面重新标记时会被标记成黑色,这个时候就不会被删掉了
最后似乎推荐了一下jdk9
八、垃圾回收-GC调优
新生代不是越大越好,新生代太大会挤压老年代,容易发生full GC,消耗更多时间;同时,因为大部分时间都发生在复制上,所以调大新生代,不会减少复制的时间,也就无法调优。调大新生代一定程度上可以减少响应时间。
幸存区:当幸存区过小的时候,jvm会自动将晋级条件调低,导致活跃数据提前进入老年区,这样就必须等到下次老年代内存不够,触发full GC才能回收
老年代:如果没发生full GC,则暂时不考虑调老年代。老年代的空间是越大越好的。