1. 程式人生 > >String字串詳解

String字串詳解

參考文章

事件描述

由於公司的需要需要從日誌中拉取一些重要的資料,於是通過readLine方法來獲取資料,一個日誌檔案的大小500M-1G不等。於是思考,String字串不是放常量池的嗎?常連池是放在方法區,方法區屬於永久區。那麼如果這個專案當做一個拉取日誌的專案,很有可能會把永久區給OOM。但是並沒有發生這樣的情況,那麼讓我們深入的瞭解下吧。

java的String發生的是哪種OOM

按照上面傳統思維發生OOM應該是永久區報錯:java.lang.OutOfMemoryError:PermGen space
實際情況jdk1.8的String常連池已經放到了堆裡面,所以大量的字串的建立並不會出現永久區的OOM,而是會出現堆的OOM即:java.lang.OutOfMemoryError:Java heap spacess
ps:當然jdk1.8永久區也已經改名字了改為( Metaspace)。

String的儲存總結

對字串不太瞭解的同學可以看下上面的3個參考地址。我這裡只做下總結。
1:首先不管以何種方式建立String都會在字串常量池中備份一個字串。
2:只要不是新建字串的情況,那麼都會在編譯期間確定String的存放位置和值。比如
String a=”helloworld”;
String b=”hello”+”world”;
a==b//true;
下面借用別人的圖來表達一下常量池,棧,堆直接關係。
這裡寫圖片描述
這裡寫圖片描述
3:特別需要注意的是new String(),toString(),拼接”“,都是使用的堆中的物件。
Note:雖然有時候String是放在字串池中,但是並不是意味著那個字串一直存在,那個字串隸屬於當前的執行緒,如果當前的執行緒如果結束,那麼這些String不管在堆裡還是字串池中都會被gc回收。這個字串池和常量池還是有一定區別的,謹記不要搞混。
最後請思考下面這個問題:

public class Test {
    public static final String string2 = "java";
    public static void main(String[] args) {
        String string2 = "java";
    }
}