内存无人认领的静力学

时间:2013-05-27 03:14:49

标签: java

这是一种我怀疑的想法,并想过要把它扯出来 假设我有以下类作为我的应用程序的一部分加载:

class HeavyClass {
    static final ArrayList list = new ArrayList(100);
}

静态成员的生命周期是否与应用程序对齐,而不管HeavyClass实例发生了什么。
如果静态将自己与不是垃圾收集的类加载器内存(permgen)对齐 - 那么编程习惯用法是确保这样的对象只在需要的基础上消耗(并清理成员);假设我们必须有静态的在所有实例中共享)

2 个答案:

答案 0 :(得分:6)

类对象的生命周期中存在静态变量。也就是说,它们是在加载类时创建的,通常只有在处理ClassLoader时才会死掉。

如果要将列表附加到HeavyClass的实例,则不应将其static, 在list.clear()方法中调用finalize将为您提供unpredictable results

请参阅java language spec

8.3.1.1。静态字段

如果一个字段被声明为static,那么无论该类最终可以创建多少个实例(可能为零),都只存在该字段的一个化身。静态字段(有时称为类变量)在初始化类时实现(第12.4节)。

答案 1 :(得分:1)

  

静态成员的生命周期是否与应用程序对齐,而不管HeavyClass实例发生了什么。

差不多,是的。见BevnQ的回答。

  

如果静态将自身对齐到不是垃圾收集的类加载器内存(permgen)......

虽然(通常)在permgen中分配类的静态帧:

  1. permgen memory>>是<<收集垃圾,
  2. 来自静态帧的对象引用(例如arraylist)未在permgen中分配。
  3. 但是,这些事实实际上都没有改变任何内容......除非您的应用程序成功处理了加载相关类的类加载器。

      

    什么是编程习惯用法,以确保这样的对象仅在需要的基础上消耗(并清理成员);假设我们必须在所有实例之间共享静态)

    问题在于何时不再需要成员。如果可以重新生成成员,则可以使用弱引用实现缓存。这是一个常见的解决方案并且工作得相当好,但您可能希望对缓存大小设置限制。 (一个无界限的缓存可以消耗大量的内存,更好地用于其他事情。你不会得到OOME,但你最终会更频繁地运行GC。)

    否则,您将需要实现某种引用计数机制,并希望共享数据结构的所有“客户端”始终遵守规则。这不是一个好的解决方案。

    我的建议是弄清楚如何避免使用静态或(更一般地)永久“根可达”的大型共享数据结构。