“系统内至少保持一个对对象的引用”,这个引用指的是从栈区或方法区中发出的引用,也是安全的引用。

  类被实例化之后,是放在堆区中的,而我们是无法直接操作堆内存的!因此需要一个引用,指向堆区的某个区域,而这个引用,必须是从栈中(或方法区中)发出的,因为我们可以直接访问栈内存,如果是从堆中发出的引用,是无意义的引用,我们根本访问不到,因此会被回收。

  类的成员变量恰恰是放在堆内存中,因此由类的成员变量持有一个对象的引用,这个引用是不安全的(不安全≠无效)!!

  再举个例子,如果栈区的a局部变量指向堆中的b对象,b对象的某个成员变量指向堆中的c对象。我们可以通过a访问b,再由b访问c。假如一旦a不再指向b,那么再也访问不到b,c也不可能被访问到,即便b此时仍然指向c,但都成了无法访问的对象,b、c均会被jvm自动回收。

  单例模式中成员变量是静态的,它并不保存在堆内存中,而是在方法区中,是一块持久的内存空间,不会被自动回收,因此指向自身的引用是安全的,自身不会被回收。

  到此,如果我们把第一个例子中的成员变量改成静态的,那么test方法执行结束后,A类的对象不会被回收,程序输出结果为:“main 方法执行完毕...”。

  后提一句,堆区是整个程序共享的,因此可能会出现线程安全问题。