我必须上课,谁的对象永远不会被垃圾收集。因此,如果我将类作为静态进行,它将避免对其对象进行垃圾回收,或者是否还有其他方法可以做到这一点?
简短的回答:不。将您的类标记为静态可能无法将其保存为垃圾回收
使类静态可以避免负责加载它的特定类加载器的垃圾收集。但是,如果此类加载器选择了垃圾收集,那么通过它加载的所有类(静态或非静态)也将被垃圾收集。
通常,当您的应用程序中有多个类加载器时就是这种情况。
除此之外,当一个对象(任何对象)变得无法访问时,它选择进行垃圾收集
来自JLS(source)
当且仅当其定义的类加载器可能被垃圾收集器回收时,可以卸载类或接口[...]类和由引导加载程序加载的接口可能不会被卸载。
当相应的静态变量类加载到JVM中时,垃圾收集器不会回收静态变量。
请参阅下面的stackoverflow链接
一个对象要么是可达的,要么是不可达的,这对于它所属的哪个类没有任何意义。
如果您的对象无法访问,则它是垃圾,因为您无法联系它。
如果要在整个应用程序的生命周期中使对象生效,只需将其分配给静态变量,以便永久保持可访问状态。基本上,您正在寻找Singleton模式。
应用于类的static
修饰符仅允许嵌套类,并且它使该类成为非内部类,这意味着它不需要封闭实例。这与垃圾收集问题无关。
如果我将一个类声明为静态,那么是否会阻止其实例的垃圾收集?
没有。
(嵌套)类上的static
修饰符意味着字段上与static
不同的东西。特别是,它(几乎1)与可达性或垃圾收集无关。
有没有其他方法可以做到这一点?
如果要确保某个类的实例永远不会被垃圾回收,则必须确保它始终可以访问。
一种方法是声明一个static
变量,并将您的实例的引用分配给该变量。在正常情况下2,static
变量对于整个应用程序运行仍然可以访问,因此它们引用的对象仍然可以访问。这意味着他们不会被垃圾收集。
另一种方法是将引用保存在main(...)
方法中声明的局部变量中。
还有其他方法。
1 - 轻微的问题是,非静态嵌套类的实例具有对封闭类的实例的隐式引用。但这会影响后一种情况的可达性,而不影响前一种情况。
2 - 在某些情况下,类静态会收集垃圾,但涉及创建类加载器和动态加载。事实上,这种情况的一个更常见的问题是没有收集垃圾的类/实例。
如果您希望您的类不被垃圾收集,您必须保持它被引用。最好的方法是让你的加载器类(例如Android中的Application)保存对它的引用。只要应用程序处于活动状态,您就可以确保垃圾收集器不会触及您的类。确保它是一个强大的参考,而不是弱参考甚至幻像参考