2010-02-23 50 views
2

我在想內存中有多少類存在,以防內存中的其他對象訪問它?java類在內存中佔用了多少時間

例如,假設我有一些類是這樣的:

public class OrderNumber { 
private static long counter = 0; 

public static long getOrderNumber(){ 
      if (counter >= 100) { 
      return counter = 1; 
      } 
      return ++counter; 
} 
} 

我調用它從另一個類的靜態方法:

long number = OrderNumber.getOrderNumber(); 
每次我叫它

,它返回一個遞增的數字, 1,2,3,4,...

所以,我的問題是這個方法返回初始值的概率是什麼,它應該返回序列值?

+0

您是否在詢問Class Loader? http://en.wikipedia.org/wiki/Java_Classloader – 2010-02-23 20:04:40

回答

10

現在,答案是永遠的。類定義放入permanent generation,並保持到程序終止。

請注意,這是JVM上的動態語言(如JRuby)的問題,它可以即時創建類,因爲這些類會浪費空間。我相信有變化的作品,這將解決此問題 - 例如,G1 collector

2

Java文檔確實說永遠:http://java.sun.com/docs/books/tutorial/java/javaOO/classvars.html

它們與類相關聯,而不是與任何對象。類的每個實例共享一個類變量,它位於內存中的一個固定位置

+0

我剛剛閱讀了您鏈接到的文檔,並且「永遠」一詞未出現在其中。它所得到的最接近的是你所引用的那一點,它沒有提到這個類保存了多長時間,只是當'Class'對象存在時,從它創建的任何對象都會引用同一個「內存中的固定位置」 - 即相同的'Class'對象。 – 2010-02-23 20:26:39

2

有很多關於類加載的信息。這裏,例如,是一個文章:http://www.ibm.com/developerworks/java/library/j-dyn0429/

用於加載類的規則是 在JVM規範 詳細闡述。其基本原理是 的類只加載時需要 (或者至少看起來是 加載這種方式 - 在JVM在實際裝載一些 靈活性,但 必須保持 類初始化的固定順序)。 獲取加載的每個類可能具有其它依賴的類 ,因此加載 過程是遞歸的。

這是關於加載的JVM規範。 http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html

+0

我不確定你的第三段是否正確。即使一個'Class'對象引用了'ClassLoader',如果沒有其他引用它,它仍應該有資格收集,對吧? AFAIK,'ClassLoader'本身並沒有強烈引用'Class'對象,所以他們沒有收集到的唯一原因是它們被添加到永久代中,正如daveb指出的那樣。 – 2010-02-23 20:20:59

+0

@Daniel Pryden:好點。刪除。 – 2010-02-23 20:23:24

3

它被定義爲從一個類到它的類加載器實例以及從一個類加載器實例到它加載過的每個類的有效引用。所以一個類只能與一個類加載器同時卸載(給予或採取奇怪的最終復活技巧)。每個由類加載器加載的類都可以同時收集。

實際上,班級數據存在於「永久代」(至少在HotSpot中)。這通常比主堆更少收集垃圾,因爲它應該有更少的流失。班級裝載機「泄漏」的情況也不少見。大多數應用程序的代碼會持續到進程重新啓動。開發應用程序服務器通常會重新加載「應用程序」,同時維護核心服務器/容器和一些庫代碼。

IIRC,JDK 1.1卸載了導致問題的單個類(Java 2在1998年推出)。

相關問題