【10-JVM面试专题-怎么判断一个对象是不是垃圾呢?对象被判定为不可达对象之后就会立即被回收吗?什么时候进行垃圾回收呢?介绍一下强引用、软引用、弱引用、虚引用的区别?】

文章介绍了Java中的垃圾回收机制,包括如何判断对象是否为垃圾,使用可达性分析算法确定GCRoot,以及对象死亡需经历的两次标记过程。同时,详细阐述了强引用、软引用、弱引用和虚引用的区别,强调了它们在内存管理和防止内存泄漏中的作用。

怎么判断一个对象是不是垃圾呢?对象被判定为不可达对象之后就会立即被回收吗?什么时候进行垃圾回收呢?介绍一下强引用、软引用、弱引用、虚引用的区别?

在这里插入图片描述

怎么判断一个对象是不是垃圾呢?对象被判定为不可达对象之后就会立即被回收吗?什么时候进行垃圾回收呢?介绍一下强引用、软引用、弱引用、虚引用的区别?你掌握的怎么样呢?

怎么判断一个对象是否为垃圾?

  • 引用计数法
    对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任何指针对其引用,它就是垃圾。
    存在的问题:循环引用的问题,会导致内存泄漏的问题,内存泄漏的堆积会直接导致内存溢出。
  • 可达法分析算法
    从一个根节点位置出发搜索,构成一条类似于链表的引用链;

可达法分析算法中能作为GC Root?

可以作为GC ROOT:静态变量、常量、栈帧中的局部变量元素,JNI也可以(GC ROOT是一个指针,不是对象)。

什么时候才会进行垃圾回收?

GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。
当然,我们可以手动进行垃圾回收,比如调用System.gc()方法通知JVM进行一次垃圾回收,但是
具体什么时刻运行也无法控制。也就是说System.gc()只是通知要回收,什么时候回收由JVM决
定。但是不建议手动调用该方法,因为GC消耗的资源比较大

  1. 当Eden区或者S区不够用了
  2. 老年代空间不够用了
  3. 方法区空间不够用了
  4. System.gc() 时机不确定 FullGC

对象被判定为不可达对象之后就会立即被回收吗?

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

  1. 第一次标记
    如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记,随后进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。假如对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,那么虚拟机将这两种情况都视为“没有必要执行”。反之,该对象将会被放置在一个名为F-Queue的队列之中,并在稍后由一条由虚拟机自动建立的、低调度优先级的Finalizer线程去执行它们的finalize()方法。
  2. 第二次标记
    稍后,收集器将对F-Queue中的对象进行第二次小规模的标记。如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移出“即将回收”的集合。如果对象这时候还没有逃脱,那基本上它就真的要被回收了。
    finalize()方法是对象逃脱死亡命运的最后一次机会,需要注意的是,任何一个对象的finalize()方法都只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会被再次执行。另外,finalize()方法的运行代价高昂,不确定性大,无法保证各个对象的调用顺序,如今已被官方明确声明为不推荐使用的语法。

简单概括一下:
不是的,我们会进行垃圾筛选回收,第一次是我们判断没有被GC ROOT标记的对象是否执行了Finalize()方法,如果没有执行,意味着当前对象没有必要被回收,当时如果执行了该方法,我们就会把它放到F-Queue对象汇总,通过一个Finalizaler线程对他进行筛选回收。第二次,我们判断队列中的对象此时是否有引用指向它,如果有的话,直接移除,如果还没有话,我们最后直接回收。

介绍一下强引用、软引用、弱引用、虚引用的区别?

  1. 强引用

JVM内存管理器从根引用集合(Root Set)出发遍寻堆中所有到达对象的路径。当到达某对象的任意路径都不含有引用对象时,对这个对象的引用就被称为强引用

  1. 软引用
    2.1 基本概念:软引用是用来描述一些还有用但是非必须的对象。对于软引用关联的对象,在系统将于发生内存溢出异常之前,将会把这些对象列进回收范围中进行二次回收。(当你去处理占用内存较大的对象 并且生命周期比较长的,不是频繁使用的)
    2.2 存在的问题:软引用可能会降低应用的运行效率与性能。比如:软引用指向的对象如果初始化很耗时,或者这个对象在进行使用的时候被第三方施加了我们未知的操作。
    2.3 使用场景: 软引用在实际中有重要的应用,例如浏览器的后退按钮。按后退时,这个后退时显示的网页内容是重新进行请求还是从缓存中取出呢?这就要看具体的实现策略了。
  • 如果一个网页在浏览结束时就进行内容的回收,则按后退查看前面浏览过的页面时,需要重新构建
  • 如果将浏览过的网页存储到内存中会造成内存的大量浪费,甚至会造成内存溢出
  1. 弱引用
    弱引用(Weak Reference)对象与软引用对象的最大不同就在于:GC在进行回收时,需要通过算法检查是否回收软引用对象,而对于Weak引用对象, GC总是进行回收。因此Weak引用对象会更容易、更快被GC回收

  2. 虚引用
    也叫幽灵引用和幻影引用,为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。也就是说,如果一个对象被设置上了一个虚引用,实际上跟没有设置引用没有任何的区别 一般不用,辅助咱们的Finaliza函数的使用

总结:

JVM知识在面试过程中非常高频,大家一定要牢牢掌握,如果以上文章有帮助到你,希望可以点个关注,留下属于你的足迹,比心!我们下节再见哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值