终结 finalize()和垃圾回收(garbage collection)

简介: 1、为什么要有finalize()方法?     假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以他不知道该如何释放该对象的这块“特殊”内存,为了应对这种情况,java 允许在类中定义一个finalize()的方法。

1、为什么要有finalize()方法?

    假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以他不知道该如何释放该对象的这块“特殊”内存,为了应对这种情况,java 允许在类中定义一个finalize()的方法。

    protected void finalize(){
        
    }

  

2、finalize()方法在何时调用?

    一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

 

3、finalize()的局限性?

  •     对象可能不被回收。
  •     垃圾回收并不等于“析构”。
  •     垃圾回收值与内存有关。

    对于与垃圾回收有关的任何行为来说(尤其是finalize()方法),他们也必须与内存及其回收有关,所以在finalize()方法内做普通的清除工作是不合适的。

    那么在finalize()中释放对象是否正确呢?不!如果JVM 并未面临内存耗尽的情形,它是不会浪费时间在回收垃圾上的。即使,JVM进行了垃圾回收, 也无法确切地保证垃圾回收器何时调用该方法,也无法保证调用不同对象的方法的顺序。即使一个对象包含另一个对象的引用,或者在释放一个对象很久以前就释放了另一个对象,也可能会以任意的顺序调用这两个对象的Finalize方法。如果必须保证采用特定的顺序,则必须提供自己的特有清理方法。

 

4、finalize()用途?

    既然finalize()这么废,好像什么都不了,那么到底用它来干嘛呢?

    当“使用本地方法”分配内存,例如使用malloc()分配存储空间,除非调用free()否则内存空间将得不到释放,从而内存泄露。因此free方法就应该在finalize()中用本地方法调用它。

     要是对象代表一个打开的文件,在对象被回收前程序员应该关闭这个文件。再要对象中存在没有被适当清除的部分,你的程序就存在很隐晦的错误,finalize()的价值就是用来最终发现这种情况。-------《Thinking in Java》

     个人认为,finalize()还是太不可靠,平常还是少用的好。

      如果一定要进行回收动作,最好自己写一个回收方法dispose()方法。应当注意的是如果子类重写了父类的dispose()方法,当进行清除动作时,应该先清除子类的,再清除父类的,原因在于:可能子类存在对父类的方法调用。

 

5、垃圾回收器如何工作?

    在某些Java虚拟机中,堆的实现方式就像一个传送带,你每分配一个新对象,它就往前移动一格,这意味着对象存储空间的分配速度非常快。但是,堆的工作又不完全像传送带一样,想象一下,要是堆指针不断向前,势必会导致频繁的内存调度,并最终耗尽资源。其中的秘密在于垃圾回收器的介入。当它工作时,将一面回收空间,一面使堆中的对象紧凑排列,这样“堆指针”就可以很容易移动到更靠近传送带的开始处,也就尽量避免了页面错误。

    垃圾回收器模式之引用计数(reference counting):是一种简单但速度很慢的垃圾回收技术。每个对象都含有一个引用计数器,当有引用连接至对象时,引用计数加1。当引用离开作用域或被置为null时,引用计数器减1。垃圾回收器会在含有全部对象的列表上,当发现某个对象的引用技术为0时,就释放其占有的空间。这种模式有种缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为0的情况”

    垃圾回收器模式之停止-复制(stop-and-copy):这种垃圾回收基于一种更快的寻找“活”的对象的方法,并能有效爱的解决对象之间的循环利用。这种方式是:遍历所有对象的引用,这个引用可能会穿过数个对象层次,并最终追溯到其存活在堆栈或静态存储区之中的引用,如果对象之间存在循环利用的话,遍历追溯到最后会发现寻找的是本身的对象,因此这些对象根本不会被发现。而stop-and-copy方式意味着先暂停程序的运行,然后将所有存活的对象从当前堆复制到另外一个堆,没有被复制的全部都是垃圾,当对象被复制到新堆时,他们是一个挨着一个的。所以新堆保持紧凑排列。值得注意的是,大型对象占有自己的内存块,copy时不进行复制,如果该对象被引用就把该内存块的代数加1来表示被引用到了。

    垃圾回收器模式之标记-清扫(mark-and-sweep): stop-and-copy存在两个问题:一、你得有两个堆,然后你得在这两个分离的堆之间来回倒腾,从而维护比实际需要多一倍的空间。某些Java虚拟机对此问题的处理方式是,按需从堆中分配几块较大的内存,复制动作发生在这些大块内存之间。二、如果稳定的程序只产生少量的垃圾,复制动作岂不是很浪费?为此引出了mark-and-sweep模式,当它遍历所有的引用,进而找出所有存活的对象,每当它找到一个存活对象,就会给对象一个标记,这个过程不会回收任何对象。只有在标记工作完成后,没被标记的对象被垃圾回收器回收。剩下的空间的不连续的,垃圾回收器要是希望得到连续空间的话,就得重新整理剩下的对象。对一般用途而言,mark-and-sweep 方式速度相当慢,但是用在处理少量垃圾或不产生垃圾时,它的速度就很快了。mark-and-sweep 工作也必须在程序暂停的情况下工作。

    垃圾回收器采用的 自适应 的技术,按照需求在各个模式之间切换,当JVM监视到所有对象都很稳定,只产生了少量的垃圾,就自动采用mark-and-sweep模式,要是堆空间出现很多碎片,就会切换回 stop-and-copy方式。

    

目录
相关文章
|
2月前
|
监控 算法 Java
深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
|
5月前
|
算法 Java
垃圾回收机制(Garbage Collection,GC)是Java语言的一个重要特性,它自动管理程序运行过程中不再使用的内存空间。
【6月更文挑战第24天】Java的GC自动回收不再使用的内存,关注堆中的对象。通过标记-清除、复制、压缩和分代等算法识别无用对象。GC分为Minor、Major和Full类型,针对年轻代、老年代或整个堆进行回收。性能优化涉及算法选择和参数调整。
68 3
|
5月前
|
算法 Java
Java垃圾回收(Garbage Collection,GC)是Java虚拟机(JVM)的一种自动内存管理机制,用于在运行时自动回收不再使用的对象所占的内存空间
【6月更文挑战第18天】Java的GC自动回收内存,包括标记清除(产生碎片)、复制(效率低)、标记整理(兼顾连续性与效率)和分代收集(区分新生代和老年代,用不同算法优化)等策略。现代JVM通常采用分代收集,以平衡性能和内存利用率。
70 3
|
6月前
|
算法 Java
Java内存管理,什么是垃圾回收机制(Garbage Collection)?
Java内存管理,什么是垃圾回收机制(Garbage Collection)?
45 1
|
6月前
|
存储 JavaScript 前端开发
JavaScript知识总结 终结篇--面向对象,垃圾回收与内存泄漏
JavaScript知识总结 终结篇--面向对象,垃圾回收与内存泄漏
|
存储 Java 开发者
【python进阶】Garbage collection垃圾回收2
【python进阶】Garbage collection垃圾回收2
169 0
【python进阶】Garbage collection垃圾回收2
|
存储 算法 Java
【python进阶】Garbage collection垃圾回收1(下)
【python进阶】Garbage collection垃圾回收1
154 0
【python进阶】Garbage collection垃圾回收1(下)
|
算法 Java 程序员
【python进阶】Garbage collection垃圾回收1(上)
【python进阶】Garbage collection垃圾回收1
171 0
【python进阶】Garbage collection垃圾回收1(上)
|
22天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
45 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
30天前
|
存储 Java PHP
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
46 0