首页 > 试题广场 >

对于一个已经不被任何变量引用的对象,当垃圾回收器准备回收该对

[单选题]
对于一个已经不被任何变量引用的对象,当垃圾回收器准备回收该对象所占用的内存时,将自动调用该对象的哪个方法()
  • finalize
  • notify
  • notifyAll
  • hashCode

垃圾回收过程中的对象销毁–Finalization

就在移除一个对象并回收它的内存空间之前,Java垃圾回收器将会调用各个实例的finalize()方法,这样实例对象就有机会可以释放掉它占用的资源。尽管finalize()方法是保证在回收内存空间之前执行的,但是对具体的执行时间和执行顺序是没有任何保证的。多个实例之间的finalize()执行顺序是不能提前预知的,甚至有可能它们是并行执行的。程序不应该预先假设实例执行finalize()的方法,也不应该使用finalize()方法来回收资源。

  • 在finalize过程中抛出的任何异常都默认被忽略掉了,同时对象的销毁过程被取消
  • JVM规范并没有讨论关于弱引用的垃圾回收,这是明确声明的。具体的细节留给实现者决定。
  • 垃圾回收是由守护进程执行的
发表于 2015-09-17 00:56:13 回复(5)

这个主要考察答题者是否了解 GC对不可用对象的判断过程,大家不要只是去了解finalize()方法,这样容易感到迷惑,如果这个题答不上来,最好还是去了解一下GC对哪些内存进行了回收以及对不可用对象的判断。

下面是 “ GC对哪些内存进行了回收 ” 的一个简单的回答:

gc是对不可用的对象进行回收,判断一个对象是否不可用采用的是可达性分析算法,具体的做法就是:从“GC Roots”开始,向下搜索,如果从GC Roots到某个对象不可达,那么这个对象就是不可用的,会被判定为是可回收的对象。

不过这些对象也不是立即就会被回收,真正宣告一个对象死亡需要至少经历两次标记过程。

  • 在通过可达性分析后发现某个对象没有和GC Roots相连接的引用链,那么这个对象会被第一次标记并且进行一次筛选。
    • 筛选的条件是:该对象是否需要执行finalize()方法
      • 如果该对象没有覆盖finalize()方法 or finalize()方法已被虚拟机调用过,则无需执行finalize()方法。
      • 否则,需要执行finalize()方法
        • 在执行finalize()方法中该对象可以进行自救,即尝试将自己与引用链上任何一个对象建立关联(比如将自己赋值给某个类变量 or 对象的成员变量)
          • 如果自救成功,在第二次标记时,该对象将从“即将回收”的集合中被移出。
          • 如果自救失败,那么基本上这个对象就会真的被回收。
发表于 2018-04-17 12:29:33 回复(3)

在Java虚拟机的垃圾回收器看来,堆区中的每个对象都可能处于以下三个状态之一。
 可触及状态:当一个对象(假定为Sample对象)被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
 可复活状态:当程序不再有任何引用变量引用Sample对象时,它就进入可复活状态。在这个状态中,垃圾回收器会准备释放它占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的finalize()方法,这些finalize()方法有可能使Sample 对象重新转到可触及状态。
 不可触及状态:当Java虚拟机执行完所有可复活对象的finalize()方法后,假如这些方法都没有使Sample对象转到可触及状态,那么Sample对象就进入不可触及状态。只有当对象处于不可触及状态时,垃圾回收器才会真正回收它占用的内存。

notify唤醒线程,与wait()和同步锁synchronized()方法配合使用

发表于 2015-10-13 22:16:41 回复(1)
java中回收机制是自发的,无需人为操作finalize是这种机制执行时需要调用的函数,可以人为更改
发表于 2015-10-07 20:21:47 回复(2)

finalize方***在两种情况下被调用

  1. GC时,没有变量引用的对象会被调用finalize方法
  2. 程序结束时,所有的对象都会被调用finalize方法
发表于 2016-11-12 17:20:28 回复(0)
finalize-方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 垃圾收集器只知道释放那些由new分配的内存,所以不知道如何释放对象的“特殊”内存。为解决这个问题,Java提供了一个名为finalize()的方法,它的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作(如关闭流等操作)。但JVM(Java虚拟机)不保证此方法总被调用。
发表于 2016-10-17 15:57:58 回复(0)
在Java虚拟机的垃圾回收器看来,堆区中的每个对象都可能处于以下三个状态之一。  可触及状态:当一个对象(假定为Sample对象)被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。  可复活状态:当程序不再有任何引用变量引用Sample对象时,它就进入可复活状态。在这个状态中,垃圾回收器会准备释放它占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的finalize()方法,这些finalize()方法有可能使Sample 对象重新转到可触及状态。  不可触及状态:当Java虚拟机执行完所有可复活对象的finalize()方法后,假如这些方法都没有使Sample对象转到可触及状态,那么Sample对象就进入不可触及状态。只有当对象处于不可触及状态时,垃圾回收器才会真正回收它占用的内存。 notify唤醒线程,与wait()和同步锁synchronized()方法配合使用
发表于 2016-08-14 13:31:50 回复(0)
对于一个已经不被任何变量引用的对象,当垃圾回收器准备回收该对象所占用的内存时,将自动调用该对象的 finalize方法。

垃圾回收过程中的对象销毁–Finalization

就在移除一个对象并回收它的内存空间之前,Java垃圾回收器将会调用各个实例的finalize()方法,这样实例对象就有机会可以释放掉它占用的资源。尽管finalize()方法是保证在回收内存空间之前执行的,但是对具体的执行时间和执行顺序是没有任何保证的。多个实例之间的finalize()执行顺序是不能提前预知的,甚至有可能它们是并行执行的。程序不应该预先假设实例执行finalize()的方法,也不应该使用finalize()方法来回收资源。

  • 在finalize过程中抛出的任何异常都默认被忽略掉了,同时对象的销毁过程被取消
  • JVM规范并没有讨论关于弱引用的垃圾回收,这是明确声明的。具体的细节留给实现者决定。
  • 垃圾回收是由守护进程执行的

发表于 2017-01-09 08:42:07 回复(0)
A
发表于 2015-10-07 18:00:44 回复(0)