天天看点

笔记 - GC收集器一、分代:

一、分代:

笔记 - GC收集器一、分代:
  • 不被引用的对象会被回收
  • 垃圾回收包括Minor GC、Major GC 和 Full GC
  • 垃圾回收时所有运行暂停

注意项:

  1. 对象创的太多太快的时候也会触发GC
  2. 对象被回收时资源不会被回收 - 例如数据库连接资源需要close等
  3. try(回收资源) catch finally(回收资源)
  4. 新生代中存活一定次数后会被转入老生代
  5. Major/Full GC 会对老生代动手(发生可能性较小,一般采用Compact算法)

二、通过根节点进行回收:

笔记 - GC收集器一、分代:

1、三个回收算法 - GC会根据不同环境选择其中的算法

(1)、朴素算法:Mark And Sweep - 标记并清除

笔记 - GC收集器一、分代:

缺点: 回收后碎片化严重 (当有对象需要占用)两个内存块时便分配不进去)  :内存在物理上可能不是连续的

(2)、朴素算法:Compact - 紧凑排列 (常用于老年代)

笔记 - GC收集器一、分代:

缺点: 每块内存的大小不一致,移动到空余的空间时会导致重合等问题,因此需切成比例单位再进行移动(性能会损失)。

笔记 - GC收集器一、分代:
笔记 - GC收集器一、分代:
笔记 - GC收集器一、分代:

(3)、朴素算法:Copy (常用于新生代)

笔记 - GC收集器一、分代:

缺点: 栈内存一分为二,回收的性能提升,但内存空间少了 (空间换性能)

笔记 - GC收集器一、分代:
笔记 - GC收集器一、分代:

-- 默认算法

笔记 - GC收集器一、分代:
笔记 - GC收集器一、分代:

三、GC回收参数配置:

  1.  -XX:NewRatio 老生代/新生代比例,默认 2  (2:1)
  2. -XX:SurvivorRatio Eden/Survivor比例,默认 8 (8:1:1) 刚好10份
  3. -XX:MaxTenuringThreshold 新生代转至老生代阈值,默认15 (在新生代中存活15次即转入老生代)

四、Permanent Generation 永久代 (Java 8之前的持久代)

-- 一般配置参数 -XX:PermSize=5M -XX:MaxPermSize=7M

  1. 放置ClassLoader读进来的Class,除系统Class外 
  2. String.intern  - 结果被存入持久代作缓存
  3. 方法区也位于永久代(PermGen)
  4. 缺点: 易出现OutOfMemoryError: PermGen Space -> 使用 -XX:MaxPermSize调整

五、Metaspace 元空间 (Java 8 以后)

-- 配置传送门: https://blog.csdn.net/bolg_hero/article/details/78189621

  1. 仍然放置ClassLoader读进来的Class,除系统Class外 
  2.  String.intern的结果被放入堆
  3.  Metaspace 默认不受限制,使用的是系统内存

点总结:

  •  java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;
  • java7中,static变量从永久代移到堆中;
  • java8中,取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中

六、垃圾回收常见问题

问题 : 谈谈Java垃圾回收机制 

      1、垃圾回收在什么时候运行?

  • 内存满了或分配内存失败的时候运行,手动调用运行(System.GC) - 用于调试内存问题

      2、垃圾回收对什么对象进行回收?

  • 通过根节点出发,顺着引用关系,看得到的引用对象都是需要保留的,而没有引用的对象需进行回收。
  • 注意:Java不用引用计数(对象依赖)来进行标记mark

      3、垃圾回收算法对内存划分成了哪些区域

  • 新生代(eden,survivor1,survivor2)、老生代、持久代(Java 8的Meta space)
  • 新生代里面采用 copy 的算法,将eden拷贝到survivor1……
  • 老生代 采用 Compact的算法。
  • 新生代转至老生代阈值 新生代的survivor通过配置里的数目会进入老生代 -XX:MaxTenuringThreshold (默认15) 
  • MetaSpace/Java 8以前的持久代 放置ClassLoader产生的Object。

      4、 触发FullGC的条件

  • 笔记 - GC收集器一、分代:

七、Java垃圾回收的调试  - 工具或配置

1、获取信息

  • -verbose:gc -- 配置 可往控制台输出垃圾回收信息
  • -XX:+HeapDumpOnOutOfMemoryError -- 配置 一般在生产环境会打开,当内存溢出时会有HeapDump报告(用于分析)
  • -XX:HeapDumpPath=d:\oom.dump 路径存储
  • -XX:+PrintGCDetails - Xloggc:<GC-log-file-path> -- 配置 获得GC日志
  • Spring Actuator - 可以获得内存信息 -- 工具 Spring工具

2、查看信息

  • 官方: visualvm,jmap
  • Eclipse Memory Analyzer (MAT)
  • 在线: gceasy.io、fastthread.io  通过日志上传查看报告和解决方案