关于Java垃圾回收问题

开发 后端
Java垃圾回收器负责回收无用对象占据的内存资源.但也有特殊情况:假定你的对象(并非使用new)获得了一块"特殊"的内存区域,这极大的简化了程序开发人员的工作,但Java垃圾回收器也有其自身的问题。

Java垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块"特殊"内存.为了应对这种情况,Java允许在类中定义一个名为finalize()的方法.它的工作原理"假定"是这样的:一旦Java垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法.并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存.所以要是你打算用finalize(),就能在垃圾回收时刻做一些重要的清理工作.也许你会发现,只要程序没有濒临丰储空间用完的那一刻,对象占用的空间就总也得不到释放,如果程序执行结束,并且垃圾回收器一直没有释放你创建的任何对象的存储空间,则随着程序的退出,那些资源也会全部交还给操作系统.

这个策略是恰当的,因为垃圾回收本身也有开销,要是不使用它,那就不用支付这部分开销.所以你根本没有办法知道垃圾回收器会不会执行,什么时候执行.你要回收的对象不一定会被回收.finalize()方法用于清理什么样的对象?如果我要清理某个对象,而该对象中含有其它对象,finalize()就应该明确释放那些对象呢?

不----无论对象是如何创建的,Java垃圾回收器都会负责释放对象占据的所有内存.这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配存储空间.不过,大家也看到,Java中一切皆为对象,那这种特殊情况是怎么回事?看来之所以要有finalize(),是由于在分配内存时可能采用了类似C语言中的做法.而非Java中的通常做法.

这种情况主要发生在使用"本地方法"的情况下,本地方法是一种在Java中调用非Java代码的方式.本地方法目前只支持C和C++,但它们可以调用其他语言写的代码,所以实际上可以调用任何代码.在非Java代码中,也许会调用C的malloc()函数系列来分配存储空间,而且除非调用了free()函数,否则存储空间将得不到释放,从而造成内存泄露.当然,free()是C和C++中的函数,所以要在finalize()中用本地方法调用它.至此,大家或许明白了不要过多地使用finalize()的道理了.System.gc(),强行运行垃圾回收器.

finalize()在什么时候被调用?有三种情况1.对象被Garbage Collection时自动调用,比如运行System.gc()的时候.2.程序退出时为每个对象调用一次finalize方法。3.显式的调用finalize方法

除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因.

测试代码 package test;  

/**     
 * 测试垃圾回收器与finalize()方法     
 * @author Administrator     
 */     
public class GcTest {     
   public static void main(String[] args) {     
        Book b1 = new Book();     
        b1.setName("new");             
        Book b2 = new Book();     
        b2.setName("old");             
        /*     
         * 把b2引用指向null.让b2引用所指的Book对象不在有引用指向它.     
         * 垃圾回收器运行时,让对象回收掉.     
         */     
        b2 = null;           
        /*     
         * 强行运行垃圾回收器.     
         */     
        System.gc();     
    }     
}     
    
class Book{            
    private String name;     
         
    public String getName() {     
        return name;     
    }            
    public void setName(String name) {     
        this.name = name;     
    }            
    @Override     
    protected void finalize() throws Throwable {     
        // TODO Auto-generated method stub     
        super.finalize();     
        System.out.println(getName()+"--->执行GC工作.");     
    }     
}    
package test;  
/**  
 * 测试垃圾回收器与finalize()方法  
 * @author Administrator  
 */  
public class GcTest {  
   
 public static void main(String[] args) {  
  Book b1 = new Book();  
  b1.setName("new");   
  Book b2 = new Book();  
  b2.setName("old");    
  /*  
   * 把b2引用指向null.让b2引用所指的Book对象不在有引用指向它.  
   * 垃圾回收器运行时,让对象回收掉.  
   */  
  b2 = null;    
  /*  
   * 强行运行垃圾回收器.  
   */  
  System.gc();  
 }  
}  
 
class Book{   
 private String name;  
 public String getName() {  
  return name;  
 }  
 public void setName(String name) {  
  this.name = name;  
 }  
 @Override  
 protected void finalize() throws Throwable {  
  // TODO Auto-generated method stub  
  super.finalize();  
  System.out.println(getName()+"--->执行GC工作.");  
 }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.

结果代码

old--->执行GC工作. 

【编辑推荐】

  1. Java连接MySQL中文乱码处理
  2. 在Java应用程序中使用Jfreechart配置
  3. Java虚拟机内部构成浅析
  4. 浅谈Java线程的生命周期
  5. 关于Java继承的一些复习
责任编辑:彭凡 来源: javaeye
相关推荐

2021-01-04 10:08:07

垃圾回收Java虚拟机

2009-12-30 10:14:29

JVM垃圾回收

2010-12-13 11:14:04

Java垃圾回收算法

2015-04-21 11:33:37

JavaJava垃圾回收

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2022-01-20 10:34:49

JVM垃圾回收算法

2022-07-27 08:01:29

CMS垃圾回收器

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2015-07-06 10:14:25

Java垃圾回收实战

2009-07-06 17:34:22

Java垃圾回收

2009-06-23 14:15:00

Java垃圾回收

2021-11-05 15:23:20

JVM回收算法

2012-01-09 17:06:16

JavaJVM

2011-07-04 16:48:56

JAVA垃圾回收机制GC

2014-12-19 11:07:40

Java

2015-06-04 09:38:39

Java垃圾回收机

2011-06-28 12:39:34

Java垃圾回收

2020-07-09 08:26:42

Kubernetes容器开发

2021-03-03 08:13:57

模式垃圾回收

2023-12-19 21:52:51

Go垃圾回收开发
点赞
收藏

51CTO技术栈公众号