静态方法(事实上所有方法)以及静态变量存储在堆的PermGen部分,因为它们是反射数据(类相关数据,而不是实例相关)的一部分。
澄清更新:
请注意,只有变量及其技术值(原语或引用)存储在PermGen空间中。
如果您的静态变量是对对象本身存储在堆的正常部分(年轻/旧生成或幸存者空间)的对象的引用。这些对象(除非它们是类间的对象,如类等)不存储在PermGen空间中。
例:
static int i = 1; //the value 1 is stored in the permgen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the permgen section, the object itself is not.
垃圾收集的一个词:
不要依赖finalize(),因为它不能保证运行。这完全取决于JVM决定何时运行垃圾收集器和收集什么,即使一个对象是可以进行垃圾收集的。
当然,你可以设置一个静态变量为null,从而删除对堆上的对象的引用,但这并不意味着垃圾收集器将收集它(即使没有更多的引用)。
另外finalize()只运行一次,所以你必须确保它不会抛出异常或以其他方式阻止对象被收集。如果你通过一些异常停止完成,finalize()不会再次在同一对象上被调用。
最后一点是:如何存储代码,运行时数据等取决于使用的JVM,即HotSpot可能会与JRockit不同,并且这甚至可能在同一JVM的版本之间不同。以上是基于HotSpot for Java 5和6(这些基本上是一样的),因为在回答时,我会说大多数人使用那些JVM。由于Java 8中的内存模型的重大更改,上面的语句可能不适用于Java 8 HotSpot – 并且我没有检查Java 7 HotSpot的更改,因此我猜测上面的内容仍然适用于该版本,但我不确定这里。