垃圾回收机制(GC)

垃圾回收机制(GC)

  • Java GC (Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一
  • 作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题。
  1. 自动垃圾回收是查看堆内存、识别哪些对象正在使用、哪些未使用以及删除未使用对象的过程。一个使用中的对象,或一个引用的对象,意味着你的程序的某些部分仍然维护着一个指向那个对象的指针。未使用的对象或未引用的对象不再被程序的任何部分引用。因此可以回收未被引用的对象使用的内存。
  2. 在像 C 这样的编程语言中,分配和释放内存是一个手动过程。在 Java 中,释放内存的过程由垃圾收集器自动处理

1 需要GC的内存区域

  • jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理

  • 因此,我们的内存垃圾回收主要集中于 java 堆方法区中,在程序运行期间,这部分内存的分配和使用都是动态的

2 判断GC对象是否存活

判断一个对象是否存活常用的有两种办法:引用计数可达性分析

2.1 引用计数

每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。

Java没有选择使用引用计数算法管理内存。

2.2 可达性分析(Reachability Analysis)

从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。(其实就是搜寻对象是否有引用)

GC Roots包括:

  • 虚拟机栈中引用的对象。
  • 方法区中类静态属性实体引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI引用的对象。

在这里插入图片描述

通过可达性分析可以对需要回收的对象进行标记,但并不意味着一定会被回收

3 标记死亡对象

要真正宣告一个对象的死亡,至少要经历两次的标记过程

3.1 第一次标记

第一次标记前提: 在可达性分析后发现到GC Roots没有任何引用链相连时,被第一次标记。并且判断此对象是否必要执行finalize()方法!

对象被回收: 如果对象没有覆盖finalize()方法或者finalize()已经被JVM调用过,则这个对象就会认为是垃圾,可以回收。
对象不被回收: 对于覆盖了finalize()方法,且finalize()方法没有被JVM调用过时,对象会被放入一个称为F-Queue的队列中,等待着被触发调用对象的finalize()方法。

3.2 第二次标记

第二次标记前提: 执行完第一次的标记后,GC将对F-Queue队列中的对象进行第二次小规模标记。也就是执行对象的finalize()方法!

对象不被回收: 如果对象在其finalize()方法中重新与引用链上任何一个对象建立关联,第二次标记时会将其移出"即将回收"的集合。
对象被回收: 如果对象没有,也可以认为对象已死,可以回收了。

4 什么时候触发GC

  • 程序调用System. gc() 时可以触发
  • 系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值