java 主gc 次gc_深入理解 Java —— GC 机制

1. 基础知识

1.1 什么是垃圾回收?

程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢出,所以对内存资源的管理非常重要。

垃圾回收就是对这些无效资源的处理,是对内存资源的管理。

1.2 为什么要了解 GC?

在你排查内存溢出、内存泄漏等问题时,以及程序性能调优、解决并发场景下垃圾回收造成的性能瓶颈时,就需要对GC机制进行必要的监控和调节。

1.3 什么时候进行垃圾回收

会在cpu空闲的时候自动进行回收在堆内存存储满了之后

主动调用 System.gc() 后尝试进行回收

补充:System.gc() 用于调用垃圾收集器,在调用时,垃圾收集器将运行以回收未使用的内存空间。它将尝试释放被丢弃对象占用的内存。 然而System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用。所以 System.gc() 并不能说是完美主动进了垃圾回收。

1.4 GC 发生在 JVM 哪部分?

在回答这个问题之前,有必要先了解 JVM 的体系结构图:

9c71f4b1f968e1f37d2e555f1ae77b36.png

对于 JVM 各部分的解读,这里不在做过多说明,具体可以参考文章:Java 虚拟机结构。

GC主要发生在堆中,堆区由所有线程共享,在虚拟机启动时创建。堆区主要用于存放对象实例及数组,所有new出来的对象都存储在该区域。

JVM 虚拟栈,本地方法栈,程序计数器不需要进行垃圾回收,因为他们的生命周期是和线程同步的,随着线程的销毁,他们占用的内存会自动释放。所以,只有方法区和堆区需要进行垃圾回收,回收的对象就是那些不存在任何引用的对象。

2. 如何判断对象已死(或能够被回收)

既然名叫垃圾回收,那么哪些对象成为“垃圾”呢?已经不再被使用的对象便视为“已死”,就应该被回收。在Java中,GC只针对于堆内存,Java语言中不存在指针说法,而是叫引用,在堆内存中没有被任何栈内存引用的对象应该被回收。

2.1 引用记数法

既然没有引用就可以回收,引用计数法应运而生。简单的来说就是判断对象的引用数量。

实现方式:给对象共添加一个引用计数器,每当有引用对他进行引用时,计数器的值就加1,当引用失效,也就是不在执行此对象,它的计数器的值随之减1,若某一个对象的计数器的值为0,那么表示这个对象没有被其他对象引用,也就是意味着是一个失效的垃圾对象,就会被GC进行回收。

缺点:无法解决对象减互相循环引用的问题。即当两个对象循环引用时,引用计数器都为1,当对象周期结束后应该被回收却无法回收,造成内存泄漏。

2.2 可达性分析算法

目前主流使用的都是可达性分析算法来判断对象是否存活。算法基本思路:以“GC Roots”作为对象的起点,从此节点开始向下搜索,搜索所走过的路径成为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

1620

哪些对象可作为GC Roots?

虚拟机栈(栈帧中的本地变量表)中引用的对象;

方法区中类静态属性引用的对象;

方法区中常量引用的对象;

本地方法栈中JNI(Native方法)引用的对象;

活跃线程的引用对象。

在可达性分析法中,判定一个对象 objA 是否可回收,至少要经历两次标记过程:如果对象 objA 到 GC Roots没有引用链,则进行第一次标记。

如果对象 objA 重写了 finalize() 方法,且还未执行过,那么 objA 会被插入到 F-Queue 队列中,由一个虚拟机自动创建的、低优先级的 Finalizer 线程触发其 finalize() 方法。finalize() 方法是对象逃脱死亡的最后机会,GC 会对队列中的对象进行第二次标记,如果 objA 在 finalize() 方法中与引用链上的任何一个对象建立联系,那么在第二次标记时,objA 会被移出“即将回收”集合。

下面给个示例代码,具体结论,大家可以自己验证。

@Overrideprotected void finalize() throwsThrowable {super.finalize();

System.out.println("method finalize is running");

object= this;

}public static void main(String[] args) throwsException {

object= newFinalizerTest();//第一次执行,finalize方法会自救

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值