2012-05-21 54 views
5

我的理解是,PermGen(從某種意義上)在課堂上掌握了課堂代碼。通常我們有很多引用我們類路徑的jar文件。當jar文件包含在classpath中時(比如在tomcat的lib目錄下),所有這些jar的所有類都會自動加載到PermGen中?什麼時候在罐子裏的課程進入PermGen

在類似的問題中,一旦使用了一個jar文件的類,PermGen會加載該jar文件中的所有類,還是隻加載所使用的類(然後在需要時再加載其餘的類文件)?

回答

4

這取決於在一定程度上的類加載器的實現和JVM - 在Java Virtual Machine specification這樣說:

本規範允許實現靈活性何時 的活動聯繫起來(和,因爲遞歸,裝載)發生, 提供了Java編程語言的語義 尊重,[...]

例如,實現可以選擇解決一個類或接口individ每個符號 參考最後,只有在使用 (惰性或延遲分辨率)時,或者在 類正在驗證(靜態分辨率)時一次全部解決它們。這意味着在一些實施方式中, 類或接口已經被初始化之後,解析過程可以繼續。

在實踐中,任何理智的實現應該自動加載一個JAR文件中的一切,只是因爲文件中的一個類被加載,更何況只是因爲它的類路徑上。

0

只有需要的類被加載並存儲在permgen空間中。

0

JLS保證一個類在第一次需要時(並且不早於)被初始化。儘管如此,實現允許執行加載和鏈接。

+0

其實該規範明確允許預加載類。一個類在被使用之前必須被加載是非常明顯的。 –

+0

那麼初始化它們呢? –

+0

這是另一回事。我不認爲初始化與PermGen用法有關,但我認爲一個實現可能會延遲加載相關的類直到初始化。 –

2

PermGen是HotSpot的一個實現細節,Oracle表示他們希望在將來擺脫它[1]。它不屬於Java(VM)規範。只有加載的類纔會在PermGen中結束。明確地通過ClassLoader#loadClass或隱式地通過鏈接。這應該只是被使用的類(和它們的依賴關係),除非有人明確地加載了所有的類,例如。對他們進行思考。像Spring這樣的框架避免了這種情況,而是掃描了字節碼。

一個好的起點是VisualVM,它允許您觀察加載的類PermGen。

[1] JRockit沒有PermGen,在最近的HotSpot版本中,字符串實習生池不再位於PermGen中。

+1

值得注意的是,只有java.lang.Class對象,與該類的名稱和方法名稱關聯的一些java.lang.String對象以及該類所引用的靜態對象纔會被加載到PermGen中。這不像你的字節碼被加載在那裏或任何東西...... –

相關問題