静态字段是否开放用于垃圾回收?
给定一个仅在程序设置中使用的假设实用程序类:
class MyUtils {
private static MyObject myObject = new MyObject();
/*package*/static boolean doStuff(Params... params) {
// do stuff with myObject and params...
}
}
当 myObject 不再使用时,它会被垃圾收集吗?还是会在程序的生命周期中一直存在?
Given an hypothetical utility class that is used only in program setup:
class MyUtils {
private static MyObject myObject = new MyObject();
/*package*/static boolean doStuff(Params... params) {
// do stuff with myObject and params...
}
}
will myObject be garbage collected when it is no longer being used, or will it stick around for the life of the program?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
加载类时,无法选择静态变量进行垃圾回收。 当相应的类加载器(负责加载此类)本身被收集为垃圾时,可以收集它们。
查看 JLS 第 12.7 节卸载类和接口
Static variables cannot be elected for garbage collection while the class is loaded. They can be collected when the respective class loader (that was responsible for loading this class) is itself collected for garbage.
Check out the JLS Section 12.7 Unloading of Classes and Interfaces
静态变量由 ClassLoader 引用的 Class 对象引用 - 所以除非 ClassLoader 以某种方式删除 Class(如果可能的话)或者 ClassLoader 本身有资格收集(更有可能 - 考虑卸载 webapp)静态变量(或相反,它们引用的对象)将不会被收集。
Static variables are referenced by Class objects which are referenced by ClassLoaders -so unless either the ClassLoader drops the Class somehow (if that's even possible) or the ClassLoader itself becomes eligible for collection (more likely - think of unloading webapps) the static variables (or rather, the objects they reference) won't be collected.
myObject 是一个引用,而不是对象。
当一个对象因为无法访问而没有引用指向它时,它会被自动垃圾回收。
因此,如果您取消引用静态引用“myObject”后面的对象
并且没有对此对象的其他引用,则该对象也可以被垃圾收集。
然而,静态引用和变量在程序的整个生命周期中仍然保留。
myObject is a reference and not an object.
An object is automatically garbage collected when no reference points to it because it is unreachable.
So also the object behind a static reference "myObject" can be garbage collected if you dereference it with
and there are no other references to this object.
However static references and variables remain for the lifetime of your program.
如果你想要一个临时对象用于静态初始化然后处理掉,你可以使用静态初始化块,例如,
由于静态初始化块是一种特殊的静态方法,myObject是一个局部变量,可以在块执行完毕。
If you want a temporary object to be used for static initialisation then disposed of, you can use a static initialiser block, e.g.
since the static initialiser block is a special kind of static method, myObject is a local variable and can be garbage collected after the block finishes executing.
我认为 这 回答了你的问题 - 基本上不会,除非该类来自一个特殊的类加载器并卸载该类。
I think this answers your question - basically not unless the class comes from a special class loader and that unloads the class.
这里的关键是类实例(即对象)的垃圾收集。 ClassLoader 实例本质上是一个对象。 因此,如果 Classloader 对象没有被垃圾回收,那么存储在堆中的任何引用(即静态内容)几乎永远不会被垃圾回收。 字符串池是个例外。
所以在你突然决定这样做之前
private static MyGiantClass myGiantObject = new MyGiantClass()
请三思而后行,因为我已经从惨痛的教训中学到了这一点。
The key here is the Garbage Collection of Class instances i.e. Objects. ClassLoader instance is, in essence, an Object. So if the Classloader object is not garbage collected, any references of them stored in heap (i.e. static stuff) will almost never be garbage collected. The exception is String pool.
So before you suddenly decide to do
private static MyGiantClass myGiantObject = new MyGiantClass()
Think twice as I have learnt the hard way.