理解Java的垃圾回收机制

一、什么对象需要GC?
jvm定义了两种算法来标明什么对象是可回收对象;
1.引用计数算法:
即对象被引用过一次后加1,引用失效后减1;任何时刻,对象引用为0时即可判定为垃圾,可以被回收;
这种算法简单高效但有很大的弊端:即两个对象被循环引用时,则两个对象的标记都一直为1,这样的对象就无法被回收;
2、可达性分析算法:
java规定了一系列对象为GC Root,以这个GC Root为起点,向下搜索它引用的对象,可以生成一个引用树。树的节点视为可达,反之视为不可达,不可达的对象就会被回收;这样可以避免循环引用的问题;
java规定了以下对象为GC Root对象:
1.虚拟机栈(具体指的是栈帧中局部变量表的slot)所引用的对象;
2.方法区中静态变量所引用的对象;
3.方法区中常量引用的对象;
4.本地方法栈引用的对象;
二、GC有哪几种方式?
1.标记清除方法
将GC分为两个阶段:1.标记阶段 为每个对象做上是否可回收的标志 2.按照标记进行回收;
特点:该算法清楚分布随机的对象时,会产生大量碎片;
2.复制算法
将内存一分为二(分为A、B两块),只在A块创建对象。当A区域中的对象要装满时,将区域中的存活对象复制至B区,然后将A区清空;
特点:适用于存活对象比较少,复制开销比较小;浪费一半的内存空间;
3.标记整理算法
该算法还是跟法1一样,先将对象进行标记,然后将存活对象进行整理,将他们都存放到一个连续的区域中,那么区域之外的对象可以一次清除;
特点:适用于存活对象比较多,回收对象比较少的情况;
4.分代回收算法(结合方法2与方法3的优势)
根据2、3算法的特点,我们发现不同类型对象的生命周期决定了该用哪种算法。于是我们将内存区域分为新生代和老生代;新生代又按照8:1:1的比例分为Eden区、SurvivorA、SurvivorB三个区域;新生代采用Copying算法,因为新生代中有大量的对象需要回收(ps:新陈代谢旺盛;而老生代可存活的对象居多,采用的是标记整理法。

问题来了,为啥Eden区域需要这么大?
因为对象刚创建的时候都是放置于Eden区域的,尤其是大量的本地变量创建的临时对象。对于这些变量而言,它们中绝大部分会被回收,能存活下来的会放入Survivor区。所以Surviror区域只需要一小块就行;这样可以大大提高内存利用率,同时也缓解了Copying算法的弊端;

那为啥要两个Survivor区域呢?
可以从垃圾回收的工作流程来理解:
1.对象不断地分配到Eden区域;
2.Eden区域满了,触发Minor GC,存活对象被复制到SurvivorA区域,Eden区域清空。
3.对象又不断的创建,Eden区域又要满了;
4.将Eden区域和SurvivorA的存活对象复制到SurvivorB中,清空Eden区域和SurvivorA区域;
5.一些对象在SurvivorA、B两个区域中来回往返15次后,这些对象会被放入老年代;
还有一些对象在Eden放不下时,会直接放入老年代中;
或者一些存活的对象放不下Survivor区域,也会直接放入老年代中;
6.当老年代区域也要满的时候,触发一次Major GC;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值