JVM GC垃圾回收简述

GC

针对java堆的回收。

可达性分析算法:从gc root搜索引用链。

Eden区满时触发minor gc,存活的对象进入survivor区(复制算法),年龄加1,当对象年龄大于阈值(默认15)时,进入老年代。可以通过参数设置阈值,虚拟机运行过程中会进行动态调整。当某个年龄大小超过survivor区一半(默认50%)时,取这个年龄和MaxTenuringThreshold中最小的作为新的阈值。

新生代(标记-复制算法)
  • 标记存活对象-因为存活对象较少
  • 内存大小eden:to:from = 8 : 1 : 1
  • minor gc后,Eden区存活的对象被复制到“survivor To”;“survivor From”区中存活的对象,年龄达到阈值就进入年老代,否则被复制到“survivor To”中。survivor From 和survivor To互换。
  • survivor From空间不够用,则放不下的部分会提前进入老年代。
老年代(标记-清除-整理算法)

老年代内存不够时进行full gc(标记-清除),多次full gc后进行整理。次数参数CMSFullGCsBeforeCompaction默认为0次。

强引用:gc不回收。
软引用:内存不足时才回收。
弱引用:gc回收。
虚引用:用于回收前,得到系统通知,可以在回收前进行一些处理。

java内存模型
  1. 程序计数器:控制程序执行。
  2. Java虚拟机栈:存储局部变量表、操作数栈、动态连接、方法出口等。
  3. 本地方法栈:存储本地(native)方法信息。
  4. Java堆:存储对象实例。
  5. 方法区:存储静态数据(常量、静态变量等)。包含运行时常量池:存储常量。
Java堆回收算法
  1. 引用计数法(多数虚拟机不用)
  2. 可达性分析算法
    根据“根对象”搜索其“引用链”判断某对象是否可达,对不可达对象进行筛选,若该对象存在finalize()方法,并且finalize()方法没被执行过,则将该对象放置于队列中,由Finalizer线程执行其finalize()方法来释放该对象。如果队列中的对象在执行finalize()释放前被重新引用,就会移出释放队列。JDK9后被移除。
回收对象判断
  1. 回收不存在引用的字符串常量(字符串常量池在堆中,运行时常量池在方法区)
  2. 不在被使用的类,仅仅是“被允许回收”
    同时满足:
    该类所有实例都被回收;
    该类的类加载器已被回收;
    该类的Class对象不存在被引用,无法进行发射访问。
GC触发条件

Minor GC触发条件:Eden区满时。

Full GC触发条件:

  1. 调用System.gc时,系统建议执行Full GC,但是不必然执行。
  2. 老年代空间不足。
  3. 方法区空间不足。
  4. 通过Minor GC后进入老年代的平均大小大于老年代的可用内存。
  5. 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。

【补充】 JDK 7 之前,HotSpot 使用永久代来实现方法区的时候,实现是完全符合这种逻辑概念的。 而在 JDK 7 及之后,HotSpot 已经把原本放在永久代的字符串常量池、静态变量等移动到堆中,这个时候类变量则会随着 Class 对象一起存放在 Java 堆中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitemeen太白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值