理解JAVA的垃圾回收机制( 二 )

// new运算符为对象动态分配内存并返回对它的引用Person p1 = new Person("John Doe");// 在使用p1期间进行一些有意义的工作.........// p1不再使用// 使p1有资格进行垃圾回收p1 = null;// 调用垃圾收集器System.gc(); // p1将被垃圾收集输出将是:

  • Person对象 - John Doe -> 成功被垃圾收集
情况2:重新分配引用变量当一个对象的引用id被引用到另一个对象的引用id时,以前的对象将不再有引用指向它 。该对象变得不可达,从而可以进行垃圾收集 。
// 创建两个Person对象// new运算符为对象动态分配内存并返回对它的引用Person p1 = new Person("John Doe");Person p2 = new Person("Jane Doe");
// 在使用p1和p2期间进行一些有意义的工作.........// p1不再使用// 使p1有资格进行垃圾回收p1 = p2;// 现在p1引用p2// 调用垃圾收集器System.gc(); // p1将被垃圾收集输出将是:
  • Person对象 - John Doe -> 成功被垃圾收集
情况3:在方法内创建对象在上一篇文章中,我们了解了方法是如何按照LIFO(后进先出)顺序存储在堆栈中的 。当这样一个方法从堆栈中弹出时,它的所有成员都会消失,如果在其中创建了一些对象,那么这些对象也会变得不可达,因此可以进行垃圾收集 。
class PersonTest {static void createMale() {// 在createMale()完成后 , 方法内的p1对象变得不可达Person p1 = new Person("John Doe");createFemale();// 调用垃圾收集器System.out.println("在createMale()中调用GC");System.gc(); // p2将被垃圾收集}static void createFemale() {// 在createFemale()完成后,方法内的p2对象变得不可达Person p2 = new Person("Jane Doe");}public static void mAIn(String args[]) {createMale();// 调用垃圾收集器System.out.println("在main()中调用GC");System.gc(); // p1将被垃圾收集}}输出将是:
在createMale()中调用GCPerson对象 - Jane Doe -> 成功被垃圾收集在main()中调用GCPerson对象 - John Doe -> 成功被垃圾收集情况4:匿名对象当对象的引用ID未分配给变量时,该对象变得不可达,从而可以进行垃圾收集 。
// 创建一个Person对象// new运算符为对象动态分配内存并返回对它的引用new Person("John Doe");// 由于没有变量分配,对象无法使用,因此它变得有资格进行垃圾回收// 调用垃圾收集器System.gc(); // 对象将被垃圾收集输出将是:
  • Person对象 - John Doe -> 成功被垃圾收集
情况5:只有内部引用的对象(孤岛)仔细观察以下两个对象如何失去其外部引用并成为垃圾收集的候选对象 。

理解JAVA的垃圾回收机制

文章插图
Image.png
编程调用GC尽管一个对象变得有资格进行垃圾收集,但它不会立即被垃圾收集器销毁 , 因为JVM会按照一定的时间间隔运行GC 。然而,使用以下任一方法,我们可以从JVM中编程地请求运行垃圾收集器(但仍然不能保证任何这些方法一定会运行垃圾收集器 。GC完全由JVM决定) 。
•使用System.gc()方法•使用Runtime.getRuntime().gc()方法
// 创建两个Person对象// new运算符为对象动态分配内存并返回对它的引用Person p1 = new Person("John Doe");Person p2 = new Person("Jane Doe");// 在使用p1和p2期间进行一些有意义的工作.........// p1和p2不再使用// 使p1有资格进行垃圾回收p1 = null;// 调用垃圾收集器System.gc(); // p1将被垃圾收集// 使p2有资格进行垃圾回收p2 = null;// 调用垃圾收集器Runtime.getRuntime().gc(); // p2将被垃圾收集


推荐阅读