class Person{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){//覆写toString方法
return "姓名:"+this.name+",年龄"+this.age;
}
public void finalize() throws Throwable{//对象释放空间时默认调用此方法
System.out.println("对象被释放-->"+this);

}
}
public class SystemDemo05{
public static void main(String[] args){
Person per = new Person("张三",30);
per =null;//断开引用
System.gc();//强制性释放空间
//Runtime.getRuntime().gc();
}
}
我运行以后貌似没有调用finalize方法为什么呢
我不是已经调用System.gc()了么
而且per的确也是垃圾内存啊。

解决方案 »

  1.   

    在JDK 1.6.20,Eclispe 3.2.1下么有问题,楼主。
      

  2.   

    我是再cmd下运行的,我的jdk是1月前下载的
      

  3.   

    -- listing properties --
    java.runtime.name=Java(TM) SE Runtime Environment
    sun.boot.library.path=C:\jdk5.0\jre\bin
    java.vm.version=20.2-b06
    java.vm.vendor=Sun Microsystems Inc.
    java.vendor.url=http://java.sun.com/
    path.separator=;
    java.vm.name=Java HotSpot(TM) Client VM
    file.encoding.pkg=sun.io
    user.country=CN
    sun.java.launcher=SUN_STANDARD
    sun.os.patch.level=
    java.vm.specification.name=Java Virtual Machine Specificatio
    user.dir=D:\java\JavaStudy\java——常用类库\System\S...
    java.runtime.version=1.6.0_27-b07
    java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
    java.endorsed.dirs=C:\jdk5.0\jre\lib\endorsed
    os.arch=x86
    java.io.tmpdir=C:\Users\lizhihui\AppData\Local\Temp\
    line.separator=

    java.vm.specification.vendor=Sun Microsystems Inc.
    user.variant=
    os.name=Windows 7
    sun.jnu.encoding=GBK
    java.library.path=C:\jdk5.0\bin;C:\Windows\Sun\Java\bin...
    java.specification.name=Java Platform API Specification
    java.class.version=50.0
    sun.management.compiler=HotSpot Client Compiler
    os.version=6.1
    user.home=C:\Users\lizhihui
    user.timezone=
    java.awt.printerjob=sun.awt.windows.WPrinterJob
    file.encoding=GBK
    java.specification.version=1.6
    user.name=lizhihui
    java.class.path=.;D:\java
    java.vm.specification.version=1.0
    sun.arch.data.model=32
    java.home=C:\jdk5.0\jre
    sun.java.command=SystemDemo03
    java.specification.vendor=Sun Microsystems Inc.
    user.language=zh
    awt.toolkit=sun.awt.windows.WToolkit
    java.vm.info=mixed mode, sharing
    java.version=1.6.0_27
    java.ext.dirs=C:\jdk5.0\jre\lib\ext;C:\Windows\Sun\...
    sun.boot.class.path=C:\jdk5.0\jre\lib\resources.jar;C:\jd...
    java.vendor=Sun Microsystems Inc.
    file.separator=\
    java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...
    sun.cpu.endian=little
    sun.io.unicode.encoding=UnicodeLittle
    sun.desktop=windows
    sun.cpu.isalist=pentium_pro+mmx pentium_pro pentium+m...这是我在cmd下查看的属性
      

  4.   

    finalize()方法何时被调用,是否被调用具有不确定性,所以不要把finalize方法当成一定会被执行的方法。
    PS:查看jdk版本 java -version就行了,不用都打出来的
      

  5.   

    谢谢,大哥,恩,我也是baidu了一下我也发现他们是这样说的,可能我看的书比较老了所以他里面是调用了
    不知道是不是新版本的java更新后他们重新做了这一块。
      

  6.   

    你可以显示调用System.gc(),但执不执行gc还是由JVM来确定,所以.....
    但在发生OOME之前,JVM一定会努力尝试去回收所以垃圾。
    还有上面提到的finalize方法,个人认为,这个方法在对象没有任何引用指向它时,在回收之前是一定会被调用的,一般finalize用来处理一些Java无法处理的资源的关闭与回收,如调用native方法后的资源回收。你的代码中没有执行finalize方法,是因为JVM还没有执行gc之前,JVM进程就已经退出了。/**
     * @ClassName: Test
     * @Description: TODO(类描述)
     * @author whwang
     * @date 2011-12-16 下午12:05:28
     * 
     */
    public class Test {
        
        private String[] strs = new String[10000];
        
        public static void main(String[] args) {
    for (int i = 0; i < Integer.MAX_VALUE; i++) {
        Test t = new Test();
    }
        }    @Override
        protected void finalize() throws Throwable {
    System.err.println("finalize....");
    super.finalize();
        }   
    }你执行下段代码。
      

  7.   

    你可以打开你的工具 然后随便新建一个对象 在这个同时 打开任务管理器 看看进程后的句柄数,也就是内存中实际的对象数目,
    假如你的工具是eclipse,看看eclipse.exe 这个进程后的句柄 然后写好垃圾回收的代码 注意 在看后面对,你的句柄数还是那么多 根本没有回收 等你那天想起来了 在去看的时候 你会发现 你的句柄数 又少了 它在不定期的实行垃圾回收 !
      

  8.   

    你永远无法知道JVM啥时候进行垃圾回收,gc()只是建议(suggest)JVM进行gc~~还有一般不需要per=null;这句,JVM比你更清楚啥时候回收它。
      

  9.   

    per = null;这样只有好处,没有坏处。
      

  10.   

    public class test {

    @Override
    protected void finalize() throws Throwable {
    super.finalize();
    System.out.println("gc");
    } public static void main(String[] args) {
    test tt = new test();
    tt = null;
    System.gc();
    // try {
    // Thread.sleep(50000);
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    }}
    输出:gc
    去掉注释也行啊。