一、分代:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPR1EeZR1TyUFVPpHOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TOzMDNzQDM0ETMwkDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
- 不被引用的对象会被回收
- 垃圾回收包括Minor GC、Major GC 和 Full GC
- 垃圾回收时所有运行暂停
注意项:
- 对象创的太多太快的时候也会触发GC
- 对象被回收时资源不会被回收 - 例如数据库连接资源需要close等
- try(回收资源) catch finally(回收资源)
- 新生代中存活一定次数后会被转入老生代
- Major/Full GC 会对老生代动手(发生可能性较小,一般采用Compact算法)
二、通过根节点进行回收:
1、三个回收算法 - GC会根据不同环境选择其中的算法
(1)、朴素算法:Mark And Sweep - 标记并清除
缺点: 回收后碎片化严重 (当有对象需要占用)两个内存块时便分配不进去) :内存在物理上可能不是连续的
(2)、朴素算法:Compact - 紧凑排列 (常用于老年代)
缺点: 每块内存的大小不一致,移动到空余的空间时会导致重合等问题,因此需切成比例单位再进行移动(性能会损失)。
(3)、朴素算法:Copy (常用于新生代)
缺点: 栈内存一分为二,回收的性能提升,但内存空间少了 (空间换性能)
-- 默认算法
三、GC回收参数配置:
- -XX:NewRatio 老生代/新生代比例,默认 2 (2:1)
- -XX:SurvivorRatio Eden/Survivor比例,默认 8 (8:1:1) 刚好10份
- -XX:MaxTenuringThreshold 新生代转至老生代阈值,默认15 (在新生代中存活15次即转入老生代)
四、Permanent Generation 永久代 (Java 8之前的持久代)
-- 一般配置参数 -XX:PermSize=5M -XX:MaxPermSize=7M
- 放置ClassLoader读进来的Class,除系统Class外
- String.intern - 结果被存入持久代作缓存
- 方法区也位于永久代(PermGen)
- 缺点: 易出现OutOfMemoryError: PermGen Space -> 使用 -XX:MaxPermSize调整
五、Metaspace 元空间 (Java 8 以后)
-- 配置传送门: https://blog.csdn.net/bolg_hero/article/details/78189621
- 仍然放置ClassLoader读进来的Class,除系统Class外
- String.intern的结果被放入堆
- 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 通过日志上传查看报告和解决方案