前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GC 基础

GC 基础

作者头像
RiemannHypothesis
发布2022-11-05 16:55:38
3890
发布2022-11-05 16:55:38
举报
文章被收录于专栏:ElixirElixir

GC的基础知识

1.什么是垃圾

C语言申请内存:malloc free C++: new delete c/C++ 手动回收内存 Java: new ? 自动内存回收,编程上简单,系统不容易出错,手动释放内存,容易出两种类型的问题:

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

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

2.如何定位垃圾
  1. 引用计数(ReferenceCount)
  2. 根可达算法(RootSearching)
3.常见的垃圾回收算法
  1. 标记清除(mark sweep) - 位置不连续 产生碎片 效率偏低(两遍扫描)
  2. 拷贝算法 (copying) - 没有碎片,浪费空间
  3. 标记压缩(mark compact) - 没有碎片,效率偏低(两遍扫描,指针需要调整)
4.JVM内存分代模型(用于分代垃圾回收算法)
  1. 部分垃圾回收器使用的模型 除Epsilon ZGC Shenandoah之外的GC都是使用逻辑分代模型 G1是逻辑分代,物理不分代 除此之外不仅逻辑分代,而且物理分代
  2. 新生代 + 老年代 + 永久代(1.7)Perm Generation/ 元数据区(1.8) Metaspace
    1. 永久代 元数据 - Class
    2. 永久代必须指定大小限制 ,元数据可以设置,也可以不设置,无上限(受限于物理内存)
    3. 字符串常量 1.7 - 永久代,1.8 - 堆
    4. MethodArea逻辑概念 - 永久代、元数据
  3. 新生代 = Eden + 2个suvivor区
    1. YGC回收之后,大多数的对象会被回收,活着的进入s0
    2. 再次YGC,活着的对象eden + s0 -> s1
    3. 再次YGC,eden + s1 -> s0
    4. 年龄足够 -> 老年代 (15 CMS 6)
    5. s区装不下 -> 老年代
  4. 老年代
    1. 顽固分子
    2. 老年代满了FGC Full GC
  5. GC Tuning (Generation)
    1. 尽量减少FGC
    2. MinorGC = YGC
    3. MajorGC = FGC
  6. 对象分配过程图
  7. 动态年龄
  8. 分配担保
5.常见的垃圾回收器
  1. 垃圾回收器的发展路线,是随着内存越来越大的过程而演进 从分代算法演化到不分代算法 Serial算法 几十兆 Parallel算法 几个G CMS 几十个G - 承上启下,开始并发回收 - .- 三色标记 -
  2. JDK诞生 Serial追随 提高效率,诞生了PS,为了配合CMS,诞生了PN,CMS是1.4版本后期引入,CMS是里程碑式的GC,它开启了并发回收的过程,但是CMS毛病较多,因此目前任何一个JDK版本默认是CMS 并发垃圾回收是因为无法忍受STW
  3. Serial 年轻代 串行回收
  4. PS 年轻代 并行回收
  5. ParNew 年轻代 配合CMS的并行回收
  6. SerialOld
  7. ParallelOld
  8. ConcurrentMarkSweep 老年代 并发的, 垃圾回收和应用程序同时运行,降低STW的时间(200ms) CMS问题比较多,所以现在没有一个版本默认是CMS,只能手工指定 CMS既然是MarkSweep,就一定会有碎片化的问题,碎片到达一定程度,CMS的老年代分配对象分配不下的时候,使用SerialOld 进行老年代回收 想象一下: PS + PO -> 加内存 换垃圾回收器 -> PN + CMS + SerialOld(几个小时 - 几天的STW) 几十个G的内存,单线程回收 -> G1 + FGC 几十个G -> 上T内存的服务器 ZGC 算法:三色标记 + Incremental Update
  9. G1(200ms - 10ms) 算法:三色标记 + SATB
  10. ZGC (10ms - 1ms) PK C++ 算法:ColoredPointers + LoadBarrier
  11. Shenandoah 算法:ColoredPointers + WriteBarrier
  12. Eplison
  13. 垃圾收集器跟内存大小的关系
    1. Serial 几十兆
    2. PS 上百兆 - 几个G
    3. CMS - 20G
    4. G1 - 上百G
    5. ZGC - 4T - 16T(JDK13)

默认的垃圾回收:PS + ParallelOld

常见垃圾回收器组合参数设定:(1.8)

  • -XX:+UseSerialGC = Serial New (DefNew) + Serial Old
    • 小型程序。默认情况下不会是这种选项,HotSpot会根据计算及配置和JDK版本自动选择收集器
  • -XX:+UseParNewGC = ParNew + SerialOld
    • 这个组合已经很少用
  • -XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old
  • -XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】
  • -XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old
  • -XX:+UseG1GC = G1
  • Linux中没找到默认GC的查看方法,而windows中会打印UseParallelGC
    • java +XX:+PrintCommandLineFlags -version
    • 通过GC的日志来分辨
  • Linux下1.8版本默认的垃圾回收器到底是什么?
    • 1.8.0_181 默认(看不出来)Copy MarkCompact
    • 1.8.0_222 默认 PS + PO

JVM调优第一步,了解JVM常用命令行参数

HotSpot参数分类

标准: - 开头,所有的HotSpot都支持 非标准:-X 开头,特定版本HotSpot支持特定命令 不稳定:-XX 开头,下个版本可能取消

java -version

java -X

java -XX:+PrintFlagsWithComments //只有debug版本能用

试验用程序:

代码语言:javascript
复制
import java.util.List;
import java.util.LinkedList;
​
public class HelloGC {
  public static void main(String[] args) {
    System.out.println("HelloGC!");
    List list = new LinkedList();
    for(;;) {
      byte[] b = new byte[1024*1024];
      list.add(b);
  }
  }
}
  1. 区分概念:内存泄漏memory leak,内存溢出out of memory
  2. java -XX:+PrintCommandLineFlags HelloGC
  3. java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGC HelloGC PrintGCDetails PrintGCTimeStamps PrintGCCauses
  4. java -XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags HelloGC
  5. java -XX:+PrintFlagsInitial 默认参数值
  6. java -XX:+PrintFlagsFinal 最终参数值
  7. java -XX:+PrintFlagsFinal | grep xxx 找到对应的参数
  8. java -XX:+PrintFlagsFinal -version |grep GC
  9. java -XX:+PrintFlagsFinal -version | wc -l 共728个参数

PS GC日志详解

每种垃圾回收器的日志格式是不同的!

PS日志格式

heap dump部分:

代码语言:javascript
复制
eden space 5632K, 94% used [0x00000000ff980000,0x00000000ffeb3e28,0x00000000fff00000)
                            后面的内存地址指的是,起始地址,使用空间结束地址,整体空间结束地址

total = eden + 1个survivor

调优前的基础概念:

  1. 吞吐量:用户代码时间 /(用户代码执行时间 + 垃圾回收时间)
  2. 响应时间:STW越短,响应时间越好

所谓调优,首先确定,追求啥?吞吐量优先,还是响应时间优先?还是在满足一定的响应时间的情况下,要求达到多大的吞吐量...

问题:

科学计算,吞吐量。数据挖掘,thrput。吞吐量优先的一般:(PS + PO)

响应时间:网站 GUI API (1.8 G1)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GC的基础知识
    • 1.什么是垃圾
      • 2.如何定位垃圾
        • 3.常见的垃圾回收算法
          • 4.JVM内存分代模型(用于分代垃圾回收算法)
            • 5.常见的垃圾回收器
              • 常见垃圾回收器组合参数设定:(1.8)
                • JVM调优第一步,了解JVM常用命令行参数
                  • PS GC日志详解
                    • 调优前的基础概念:
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档