### 深入理解jvm的內存區域
分析一段代碼,看他的各個部分存儲的位置
- 具體分配步驟如下
- 首先jvm申請一篇內存區間
- jvm活得內存空間後按照配置分配堆,棧,方法區空間
- 類加載,把class文件放入方法去區中
- 執行對象創建,放入堆中,對象引用放入棧中
堆:下面的圖片主要是展示對象的在實際內存中的存儲位置
棧:圖片主要展示棧的共享區域以及實際內存中棧裏面的屬性對應實際內存的位置
常量池
- 靜態常量池:字面量和符號引用
- 運行時常量池:每一個類或者接口常量池運行時的表現
- 字符串常量池:由於字符串是一個使用頻率極高的常量,所以jvm爲了提高效率單獨開闢一片空間存儲字符串
String
- 首先看他的結構
- String的不可變性事final決定的,這樣做的好處不可變意味着安全,且hash不會頻繁變更(因爲jvm重啓過程中會重新計算)
- String的創建以及內存分佈如下
- String str = "abc";
- String str = new String("abc");
- 對象的形式引用字符串
- String str2= "ab"+ "cd"+ "ef";這種一般編譯器優化,直接新創建一個字符串了
- 看上面這個圖片,intern方法是判斷字符串常量池內是否有這個字符串,因爲字符串都放一起了就可以檢測
內存溢出
- 堆溢出:申請的空間超過最大堆內存空間
- 棧溢出:無限遞歸
- 方法區溢出:裏面的class文件佔用內存超過配置;運行時常量池溢出
- 本機內存溢出:這個分爲內存泄漏,和jvm參數maxdirectmemorySize設置本機可用直接內存大小導致溢出的問題