如何创建一个不被回收的对象

如何创建一个不被回收的对象?
有同学问我。

最近在看JVM的我很快想到了四种引用,并回答他:只需要保持始终有一个强引用引用它就行了。

那么谁来引用这个对象呢?如何保证引用这个对象的对象不被回收呢?

确实,好像我们创建的对象都避免不了被回收的命运,不管引用链再长被回收只是时间长短问题。但是真的没有不被回收的对象吗?答案肯定有,我们细想一下,对,$JAVA_HOME中的类的对象(下文简称home对象)不会被回收除非JVM退出了。

可是,要达到我们的目标好像有点不对啊,我们需要一个不会被回收的对象引用我们,换句话说我们需要home对象引用我们,但是平时好像都是我们引用它们的呀。不对不对,好像搞反了。

要想home对象引用我们的对象,也就意味着home类依赖我们的定义的类,父类加载器依赖子类加载器加载的类,怎么可能有这种事?这样不是破坏了双亲委派模型吗?

真的不存在吗?

不,确实存在这样的事情,父类加载器依赖子类加载器加载的类,我们仔细回想一下,我们创建数据库连接的第一步是什么?

1
Class.forName("xxx.xxx.Driver")

通过这行代码将各个厂商实现的数据库驱动加载进来并注册在DriverManager中的静态final数组中:registeredDrivers

1
2
3
DriverManager.registerDriver(new Driver());
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

因为DriverManager.class在rt.jar中,由BootStrapClassLoader负责加载;
如果要回收我们注册Driver对象,意味着要卸载DriverManager类,而卸载一个类要求很严格:

  1. 该Class的所有对象都已经被回收;
  2. 该Class的类加载器已经被回收;
  3. 该类的java.lang.Class对象没有在任何地方被引用。

满足了这三个要求才会被卸载,很显然要卸载DriverManager类,第二个要求肯定满足不了。除非JVM shutdown,如果JVM已经shutdown了,我们也就没有讨论的必要了。

所以说我们可以通过这种方式实现我们的一个对象永远不被回收,虽然这样做好像没有多大的意义。。。

怎么做?
。。。
实现java.sql.Driver接口啊。