堆 棧 方法區 區別和使用
4、java堆
主要用於分配物件例項和陣列。
5、方法區
執行緒共享
用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即使編譯後的程式碼等資料。
6、直接記憶體
直接記憶體並不是虛擬機器執行時資料區的一部分。在NIO中,引入了一種基於通道和緩衝區的I/O方式,它可以使用native函式直接分配堆外記憶體,然後通過一個儲存在java堆中的DirectByteBuffer物件作為這塊記憶體的引用進行操作。
7、棧
主要存放 動態連結方法、返回值、返回地址等資訊
堆溢位
堆溢位原因莫過於物件太多導致。
2、棧溢位
根據JAVA虛擬機器規範描述:
如果執行緒請求的棧深度大於虛擬機器所允許的最大深度,將丟擲StackOverflowError
如果虛擬機器在擴充套件棧時無法申請到足夠的記憶體空間,將丟擲OutOfMemoryError。
實驗表明:
在單執行緒下,無論是由於棧幀太大還是虛擬機器棧容量太小,當記憶體無法分配的時候,虛擬機器丟擲的都是StackOverflowError。
通過不斷的建立新執行緒的方式可以產生記憶體溢位溢位。為每個執行緒的棧分配的記憶體越大,反而越容易產生記憶體溢位異常。
如果是建立過多執行緒導致的記憶體溢位,在不能減少執行緒數量或者更換64位虛擬機器的情況下,就只能通過減少最大堆和減少棧容量來換取更多的執行緒。
假設32位windows系統虛擬機器最大設為2G,虛擬機器提供了引數來控制java堆和方法區這兩部分最大值,剩餘的記憶體為2G - Xmx- MaxPermSize,如果虛擬機器本身程序記憶體大小不算在內,省下的記憶體就有虛擬機器和本地方法棧瓜分了。每個執行緒分配到的棧容量越大,可以建立的執行緒數量自然就越少。
3、方法區溢位
當執行時常量池過大或者類過多時就會導致方法區溢位。
4、直接記憶體溢位
NIO的Buffer提供了一個可以不經過JVM記憶體直接訪問系統實體記憶體的類——DirectBuffer。 DirectBuffer類繼承自ByteBuffer,但和普通的ByteBuffer不同,普通的ByteBuffer仍在JVM堆上分配記憶體,其最大記憶體受到最大堆記憶體的限制;而DirectBuffer直接分配在實體記憶體中,並不佔用堆空間,其可申請的最大記憶體受作業系統限制。
直接記憶體的讀寫操作比普通Buffer快,但它的建立、銷燬比普通Buffer慢。
堆和棧的區別:
1、儲存的東西不一樣 棧儲存 變數 引數值等, 堆儲存 方法 物件 等
2、儲存空間獲取方式不同 棧是直接獲取 如果空間不夠直接報錯,堆是先去記憶體連結串列查詢節點然後分配記憶體然後連結串列節點刪除
3、申請效率不容 棧是系統自動申請釋放 , 堆是程式設計師手動釋放free 如果不手動系統也會自動回收