2012-04-19 136 views
9

在Java中,如果字符串池的大小超過了什麼?在字符串常量池的

字符串文字都沒有垃圾收集, ,因爲它們是從表中引用這是由運行時的實例,以便優化空間中創建引用的。

如果字符串文字池的大小超過那麼, 由於字符串文字池中的每個字符串都有引用,因此它不符合GC的條件。 JVM如何處理它?

+2

字符串常量池中的* *可以被垃圾收集,如果他們不再需要(即將它們放在那裏的類被卸載)。 – 2012-04-19 08:43:56

+0

如果字符串池的大小超過*什麼*? – EJP 2016-03-08 02:43:16

回答

3

字符串文字可以在不再需要時收集。通常,如果它們出現在課堂中,這不是問題,因爲如果您嘗試加載大量課程,則可能會遇到其他限制,例如Maximum Perm通常

一般來說,開發人員足夠聰明,不會過度使用字符串文字池,而是使用數據庫或文件來加載其大部分數據(如果其大小不重要)。

如果您在嘗試優化系統空間時使用了String.intern(),您可能會引入一個問題。 String.intern()不是免費的,如果向其中添加大量(百萬)字符串,則會變得越來越昂貴。如果這是一個性能問題,那麼對開發者來說,它應該是合理的。

10

關於JavaRanch的真實代碼示例有很長的討論。

的一般輸出爲執行以下操作:收集後它不再是在使用

  1. 如果字符串在運行時使用的String.intern加入到常量池(),它可以垃圾。最有可能的是,字符串池只保留對所添加字符串的軟引用,從而允許垃圾收集它們(不能確定,因爲String.intern()是本地方法)。
  2. 如果一個字符串是一個COMPILE時間常量,它將被添加到相應類的常量池中。因此,只有在班級卸載後才能進行垃圾收集。

您的問題的答案是:由於字符串常量,您如何獲得OutOfMemoryError的唯一方法是使用在編譯時計算的許多字符串文字加載批次的類。那麼你最終可能會超過PermGen空間的最大尺寸。但是,這將在發生時加載的類到內存中(例如,啓動應用程序,部署項目,Web服務器,動態加載新的庫等)