1.什么是垃圾回收机制

在Java中,当一个对象成为垃圾后仍会占用空间内存,时间一长,就会导致内存空间的不足。。因此Java提供了垃圾回收机制(Java GC),这种机制会使得程序员不需要过多的关注垃圾回收的问题,Java虚拟机会自动的回收垃圾对象所占用的空间内存。。

2.对象在堆内存中的状态

当一个对象在堆内存中运行时,根据它被引用变量所引用的状态,可以把他所处的状态分为三种。。 alt

(1)可用状态:当一个对象被创建后,如果有一个以上的引用变量去引用它,那么这个对象在程序中处于可用状态,程序可以通过引用变量来调用该对象的实例变量和方法。

(2)可恢复状态:如果程序中某个对象不再有任何引用变量引用它,它就进入了可恢复状态。在这种状态下,系统的垃圾回收机制准备回收该对象所占用的内存,在回收该对象之前,系统会调用所有可恢复状态对象的finalize()方法进行资源清理。如果系统在调用finalize()方法前重新使一个引用变量引用该对象,则这个对象会再次进入可用状态,否则该对象会进入不可用状态。。。

(3)不可用状态:当对象失去了所有的引用变量的关联,取系统已经调用所有对象的finalize()方法后依然没有使该对象变成可用状态,那么这个对象将永久的失去引用,变成不可用状态。只有当一个对象处于不可用状态时,系统才会真正的回收该对象所占用的内存空间。。

3.Java进行垃圾回收的方法

3.1 Java虚拟机自动进行回收

一个对象在彻底失去引用成为垃圾后被暂时保存在在内存中,当这样的垃圾堆积到一定的程度后,Java虚拟机就会启动垃圾回收器将这些垃圾对象从内存中释放,从开始程序获得更多可用的内存空间。。

3.2 强制系统进行垃圾回收

虽然通过程序可以控制一个对象何时不再被任何引用对象所引用,但是却无法精确地控制Java垃圾回收的时机。除了等待Java虚拟机进行自动垃圾回收外,还可以通过如下两种方式强制系统进行垃圾回收。。

(1)调用System类的gc()静态方法:System.gc()

(2)调用RunTime对象gc()实例方法:Runtime.getRuntime().gc()

注: 调用System.gc()方法时,实际上所执行的也是Runtime.getRuntime().gc()方法。调用这两种方式强制启动垃圾回收器进行垃圾回收,但系统是否立即进行垃圾回收依然具有不确定性。。大多数情况下,强制系统进行垃圾回收总是有一定的效果的。。。

4.finalize()方法

当一个对象在内存中被释放时,它的finalize()方法会被自动调用,finalize()方法是定义在Object类中的实例方法,其原型如下:

protected void finalize() throws Throwable{}

任何Java类都可以重写Object类的finalize()方法,在该方法中清理该对象占用的资源。如果程序在终止之前仍然没有进行垃圾回收,则不会来调用失去引用对象的finalize()方法来清理资源。。

class Person{
    String person;
    public Person(String person) {
        this.person=person;
    }

    public void finalize(){
        System.out.println(person+"   对象作为垃圾会被回收");
    }
}
class Example{
    public static void recycleWaste1(){
        Person person1 = new Person("person1");
        person1=null;
        int i=0;
        while(i<10){
            System.out.println("方法1循环中.....");
            i++;
        }
    }
    public static void recycleWaste2(){
        Person person2 = new Person("person2");
        person2=null;
        //通知垃圾回收器进行强制垃圾回收
        //Runtime.getRuntime().gc();
        System.gc();
        int i=0;
        while(i<10){
            System.out.println("方法2循环中.....");
            i++;
        }
    }
}
public class test {
    public static void main(String[] args) {
        Example.recycleWaste1();
        System.out.println("================");
        Example.recycleWaste2();
    }
}

alt

如果将recycleWaste1()和recycleWaste2()调用的顺序互换,出现如下的结果:

public class test {
    public static void main(String[] args) {
        Example.recycleWaste2();
        System.out.println("================");
        Example.recycleWaste1();
    }
}

alt