初识GC与GC调优

GC的基础知识

1.什么是垃圾,怎么申请?怎么回收

C语言申请内存:malloc /free

C++: new /delete

Java: new ?(java中没有回收方法)

自动内存回收,编程上简单,系统不容易出错,手动释放内存,容易出两种类型的问题:

  1. 忘记回收
  2. 多次回收

没有任何引用指向的一个对象或者多个对象(循环引用)

2.如何定位垃圾

  1. 引用计数(计算哪些对象是否被引用了,但若三个对象相互引用,但又没有对象引用这个循环,那么就存在内存泄露《即存在垃圾》)
  2. Root Searching 根查询法:通过根变量(正在运行的线程栈变量=main方法中的局部变量、静态变量、常量池、JNI指针以及clazz文件对象)去往下推,再通过这些根变量的引用计数法,没引用的就是垃圾

3.定位后常见的垃圾回收算法

  1. 标记清除 :找到后标记,然后清除。缺点:清除后内存位置不连续 产生碎片
  2. 拷贝算法 :分配一份同样大小的内存B,每次将A中已使用的内存拷贝到B,然后清除A,下次变化时,再从B拷贝到A。优缺点:没有碎片,太浪费空间
  3. 标记压缩 :标记清除的垃圾的同时,将后面已使用内存剪切到已清除垃圾的位置,同时保证内存的连续。优缺点:没有碎片,但效率偏低

4.JVM内存分代模型(用的是分代垃圾回收算法= Generation)

  1. 是部分垃圾回收器使用的模型
  2. 由三代组成,新生代 + 老年代 + 永久代(JDK1.7)或者 新生代 + 老年代 + 元数据区(JDK1.8)
  3. 永久代/元数据区:不由堆内存管,只被操作系统限制
    1. 永久代 元数据 - 存Class对象
    2. 永久代必须指定大小限制 ,元数据可以设置,也可以不设置,无上限(元数据上线仅限于物理内存)
    3. 字符串常量 :1.7 存放再永久代,1.8 - 存放到堆中
    4. 方法区其实时一个逻辑概念 :1.7存永久代、1.8存元数据
  4. 堆内存可以分为25%新生代+75%老年代
  5. 新生代 = Eden(80%) + 2个suvivor区(各占10%):当我们new对象时,默认先存伊甸(Eden)中,若存不下,直接存入老年代中
    1. 进行一次YGC(youngGC=年轻GC)的自动回收之后,大多数(90%)的对象会被回收,活着的会通过拷贝算法 直接copy进入suvivor01区(copy效率高),再整个清除Eden区供下次使用
    2. 再次YGC,eden中活着的对象 + suvivor01活着的 ---->进入到suvivor02,清除Eden与suvivor01
    3. 再次YGC,eden中活着的对象 + suvivor02活着的 ----->进入到 suvivor01,清除Eden与suvivor02
    4. 多次YGC后,即年龄足够 -> 进入老年代 (15 CMS 6)
    5. suvivor区装不下 -> 直接进入老年代
  6. 老年代
    1. 装的都是顽固分子
    2. 老年代满了,触发一次FGC (Full GC)= YGC (新生代)+ oldGC(老年代),这种全内存垃圾回收的算法比较复杂
  7. GC Tuning (GC调优,以分代回收算法为例)
    1. 可以尽量减少FGC:需要看具体业务,有些可能要满足一个月一次FGC(这个效果就相当可以了),有些1小时或者1天一次也行
    2. MinorGC = YGC
    3. MajorGC = FGC
  8. 小结:例如一台内存为12G的机器,我们给新生代分配3G,老年代9G,那么YGC做的就是3G的垃圾回收,FGC就是12G的垃圾回收

5.常见的垃圾回收器

  1. Serial 年轻代 串行回收(程序与GC串行),例如:程序运行中,当内存满了,Serial会暂停所有正在运行的线程,触发GC,GC后再继续运行程序(这也就是为什么我们运行的应用跑了一阵时间后会出现卡顿现象,当触发GC时,程序是暂停的)
  2. PS(Paraller Scavenge) 年轻代 并行回收:可以多个线程同时进行GC
  3. ParNew 年轻代 并行回收,与PS基本一致,但ParNew可以配合CMS的
  4. SerialOld :可以理解为可以在老年代使用的Serial
  5. ParallelOld:可以理解为可以在老年代使用的PS
  6. CMS(ConcurrentMarkSweep) 老年代 并发的,很复杂但效率高, 垃圾回收和应用程序同时运行,降低STW的时间(停顿时间降到200ms)
  7. G1(停顿时间降到10ms):非分代模型的垃圾回收器,2020年后可能会用的比较多,现在大多数公司还是用的分代模型
  8. ZGC (停顿时间降到1ms) STW的效率可以PK C++了都:非分代模型的垃圾回收器
  9. Shenandoah:非分代模型的垃圾回收器
  10. Eplison:debug时用的一个垃圾回收器,一般为空的
  11. 最早的分代模型组合的就是Serial+SerialOld
  12. JDK1.8默认的垃圾回收(大多公司):PS + ParallelOld
  13. 目前来看比较好的组合:ParNew + CMS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值