这是一种我怀疑的想法,并想过要把它扯出来 假设我有以下类作为我的应用程序的一部分加载:
class HeavyClass {
static final ArrayList list = new ArrayList(100);
}
静态成员的生命周期是否与应用程序对齐,而不管HeavyClass实例发生了什么。
如果静态将自己与不是垃圾收集的类加载器内存(permgen)对齐 - 那么编程习惯用法是确保这样的对象只在需要的基础上消耗(并清理成员);假设我们必须有静态的在所有实例中共享)
答案 0 :(得分:6)
类对象的生命周期中存在静态变量。也就是说,它们是在加载类时创建的,通常只有在处理ClassLoader时才会死掉。
如果要将列表附加到HeavyClass
的实例,则不应将其static
,
在list.clear()
方法中调用finalize
将为您提供unpredictable results
。
8.3.1.1。静态字段
如果一个字段被声明为static,那么无论该类最终可以创建多少个实例(可能为零),都只存在该字段的一个化身。静态字段(有时称为类变量)在初始化类时实现(第12.4节)。
答案 1 :(得分:1)
静态成员的生命周期是否与应用程序对齐,而不管HeavyClass实例发生了什么。
差不多,是的。见BevnQ的回答。
如果静态将自身对齐到不是垃圾收集的类加载器内存(permgen)......
虽然(通常)在permgen中分配类的静态帧:
但是,这些事实实际上都没有改变任何内容......除非您的应用程序成功处理了加载相关类的类加载器。
什么是编程习惯用法,以确保这样的对象仅在需要的基础上消耗(并清理成员);假设我们必须在所有实例之间共享静态)
问题在于何时不再需要成员。如果可以重新生成成员,则可以使用弱引用实现缓存。这是一个常见的解决方案并且工作得相当好,但您可能希望对缓存大小设置限制。 (一个无界限的缓存可以消耗大量的内存,更好地用于其他事情。你不会得到OOME,但你最终会更频繁地运行GC。)
否则,您将需要实现某种引用计数机制,并希望共享数据结构的所有“客户端”始终遵守规则。这不是一个好的解决方案。
我的建议是弄清楚如何避免使用静态或(更一般地)永久“根可达”的大型共享数据结构。