1. 程式人生 > >通過Java虛擬機器理解String s=new String("abc");建立幾個物件

通過Java虛擬機器理解String s=new String("abc");建立幾個物件

以前看java虛擬機器的知識的時候都是零零散散看的,這段時間剛好自己可以有很多的時間做自己的事情了。所以抽空把《深入理解Java虛擬機器》看完了。這本書講了Java虛擬機器是如何改善程式碼的,以及我們寫的程式碼在虛擬機器上執行的時候會發生什麼,總結的一句話就是可以讓我們通過現象看到本質,讓我們寫程式碼的時候不僅僅是做一個API小王子,也可以在寫程式碼的時候優化程式,最大的感觸就是多看看一些比較出名的書,比很多入門的書感覺好多了,不過最開始的時候,我覺得看入門的比較好,畢竟可以在短時間內瞭解整個體系。話不多說,我下面開始展開一下題目上的意思。

首先,我們先了解一下java虛擬機器區的各個區域,內容部分摘抄於《深入理解Java虛擬機器》,在這裡多扯一句,那就是有時候進行虛擬機器調優的時候,如果出現記憶體溢位異常不一定說是堆記憶體太小了導致物件分配不下,也有可能是是其他區域,例如Direct Memory空間不足,因為他不是說空間不足就會進行垃圾回收,要等到老年代滿了後Full GC,然後才會幫它清理記憶體的廢棄物件。所以有的時候不一定是堆記憶體不足,要檢視是否是堆記憶體不足的話,可以檢視GC次數。出了Java堆和永久代之外,以下區域也會佔用較多的記憶體,比如說:Direct Memory:

可通過-XX:MaxDirectMemorySize調整大小,記憶體不足時丟擲OutOfMemoryError或者OutOfMemoryError:Direct buffer memory。執行緒堆疊:可通過-Xss調整大小,記憶體不足時丟擲StackOverflowError(縱向無法分配,即無法分配新的棧幀)或者OutOfMemoryError:unable to create new native thread(橫向無法分配,即無法建立新的執行緒)。Socket快取區:每個Socket連線都Receive和Send兩個快取區,分別佔大約37KB和25KB記憶體,連線多的時候這塊記憶體佔用也比較客觀。如果無法分配,可能會丟擲IOException:Too many open files異常。JNI程式碼:
如果程式碼使用JNI呼叫本地庫,那麼本地庫使用的記憶體也不在堆中。虛擬機器和GC:虛擬機器、GC的程式碼也要消耗一定的記憶體。

1.程式計數器:程式計數器是一塊較小的記憶體空間,執行緒私有,它可以看作是當前執行緒所執行的位元組碼的行號指示器。位元組碼直譯器就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令、分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能都需要依賴這個計數器來完成。

2.Java虛擬機器棧:虛擬機器棧描述的時Java方法執行的記憶體模型,執行緒私有