理解Java_GC:时机、对象、行为、算法

1.GC执行的时机

GC将堆里的对象分为新生代,老年代,持久代。新生代有一个Eden区,两个survivor区。新生成的对象直接放在Eden区,Eden区满了就放进survivor1,当survivor1满了就会出发一次Minor GC:将存活的对象放入survivor2,然后清空Eden和survivor1,再将survivor区的交换,保证survivor2为空。当survivor2不足以存放Eden和survivor1的存活对象时,就会放入老年区。较大的对象和长期存活的对象直接进入老年区。当即将进入老年区的对象超过老年区剩余大小时,触发一次full GC。
频率上说,Minor GC较频繁,full GC不频繁。
持久代会存放一些静态值和方法。

2.对象

其实就是对什么对象进行回收。比较标准的回答是:从root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象。
gc roots:
1. 虚拟机栈中的引用的对象
2. 方法区中静态属性引用的对象,常量引用的对象
3. 本地方法栈中JNI(即一般说的Native方法)引用的对象。

3.行为

新生代:复制清理。
老年代:标记-清除、标记-压缩

4.算法

1° 引用计数(早期策略)

堆中每个对象都有一个计数变量,每当有引用指向该对象时,变量加1,每当一个引用超出生命周期或指向其他对象时,变量减一。当为0时,会被认为是垃圾。
- 优点:简单,效率高
- 缺点:无法识别互相引用但不能从外部访问的对象。

2°标记-清除

从root开始扫描,对存活的对象进行标记,再扫描整个空间的对象,对没有标记的对象进行回收.
- 缺点:会造成内存碎片。

3°标记-压缩

在标记-清除后,将所有对象向空闲区移动,并更新指针。成本更高了。
- 优点:解决了内存碎片
- 缺点:增加句柄,成本高

4°复制清理

将内存空间分为对象面和空闲面。当对象面满了,就将存活的对象复制到空闲面。然后清除对象面。如果按照1:1的比例分配空间,那太浪费了。如果对象生存期都非常短,那可以减少空闲区空间,可以节省空间。如主流的虚拟机上新生代Eden:Survivor1:Survivor2=8:1:1。
- 优点:解决了内存碎片和增加句柄的问题。
- 缺点:对于生存期长的对象,浪费空间。

这是我看了网上一些大神的博客和一些学长的理解后,自己整理的我自己关于java gc的大致认识。希望可以解决你的一些小困惑。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值