Java垃圾回收机制

哪些内存需要回收?

由于程序计数器、虚拟机栈、本地方法栈是线程私有的,即随着线程生而生,线程死而死;而java堆和方法区是线程共享的,所以垃圾回收GC面向java堆(主要)和方法区。

垃圾是什么?

一个对象,使用对象存活判定算法判定,发现不是存活状态,即为可回收的垃圾。

对象存活判定算法:

1. 引用计数算法:

  • 给对象添加一个引用计数器,每当有一个地方引用它时,计数器加1;当一个引用失效时,计数器减1。对一个对象,其引用计数为0,则未被引用,即判定为可回收的垃圾。
  • 优点:算法简单,效率高
  • 缺点:不能解决对象之间相互循环引用的问题
    • eg:两个对象,除了互相引用之外,再无任何其他的引用,实际上这两个对象已经不可能被访问了,但是通过引用计数算法不能判断为可回收的垃圾。

2. 可达性分析算法(目前一般都用这种):

  • 从一个“GC Roots”出发,向下搜索,到某一个对象节点没有任何路径可达,则称“GC Roots”到这个对象不可达,即该对象不可用,可以判定为可回收的垃圾。
    • 可作为 GC Roots的对象包括:
      • 虚拟机栈中引用的对象
      • 方法区中静态属性引用的对象
      • 方法区中常量引用的对象
      • 本地方法栈中Native方法引用的对象
  • 优点:解决了引用计数算法不能解决的循环引用的问题

引用(插入讲解)

引用分为4种类型,从强到弱依次是:
强引用(Strong Reference) > 软引用(Soft Reference) > 弱引用(Weak Reference)> 虚引用(Phantom Reference)

  • 强引用:代码中普遍存在的引用形式,只要强引用存在,就不能GC回收
  • 软引用:描述一些还有用但非必需的对象,当内存不足,即将发生OOM(Out Of Memory)异常时,会加入GC回收范围,下次进行回收
  • 弱引用:同样是描述非必需的对象,但比软引用强度弱,即不管内存是否充足,下次进行GC时,会被回收
  • 虚引用(幽林引用/幻影引用):能在这个对象被收集器回收时受到一个系统通知

垃圾回收的方法?

垃圾收集算法,大致分为以下4种:标记-清除算法、复制算法、标记-整理算法、分代收集算法,其中标记-清除算法是最基础的收集算法,后面的算法都是在其基础上不断进行改进而产生的。
1. 标记-清除算法(Mark-Sweep):

  • 分为两个过程:标记和清除,先标记出所有需要回收的对象,标记完成后,再统一回收所有被标记的对象。
  • 缺点:
    • 标记和清除的效率都不高;
    • 会形成大量不连续的内存碎片,导致后面对较大对象的分配出现内存不足,而提前触发另一次GC。

2. 复制算法(Copying):

  • 将可用内存一分为二,每次只使用其中的一块;当一块用完了,就将还存活的对象复制到另一块上面,再将前一块中使用过的内存空间一次性清理掉。
  • 解决了效率和内存碎片的问题
  • 缺点:将内存缩小为原来的一半
  • 一般用于新生代

3.标记-整理算法(Mark-Compact):

  • 分为两个步骤,标记和整理,标记和标记-清除算法中类似;至于整理是指:将所有存活对象都向一端移动,然后直接清理掉端边界以外的内存。
  • 一般用于老年代

4.分代收集算法:

  • 将Java堆分为新生代和老年代
    • 新生代:对象大量死亡,少量存活,选用复制算法
      • 新生代中将内存分为3块:一块较大的Eden、两块较小的Survivor,每次使用Eden和一块Survivor
      • 当回收时,将Eden和Survivor中的存活对象复制到另一块Survivor中,再清理掉Eden和第一块Survivor空间
      • HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,即每次新生代可用内存空间为整个新生代容量的90%
    • 老年代:对象存活率高,选用标记-清理算法或标记-整理算法

内存分配和回收策略

  • 对象优先在Eden分配
  • 大对象直接进入老年代
  • 长期存活的对象将进入老年代
  • 动态对象进行年龄判定
    • 如果Survivor中相同年龄所有对象大小的总和大于Survivor空间的一半,则年龄大于或等于该年龄的对象就可以直接进入老年代
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值