JVM 內存劃分
對象的分配
分配內存 線程安全問題:緩存
- 分配動做處同步---實際上採用CAS保證分配的原子性
- TLAB 本地線程分配緩存
對象內存中的信息佈局安全
- 對象頭
- Mark word (根據對象狀態複用此部分空間)
- hashcode
- GC分代信息
- 鎖狀態信息
- 線程持有的鎖
- 偏向線程ID
- 偏向時間戳
- .....
- 類型指針(對象指向它的類元數據的指針,虛擬機能夠經過這個指針來肯定這個對象是哪個類的實例)
- 實例數據
- 對齊填充(對齊填充並非必要的,只是vm要求對象的大小必須是8的整數倍,當實例數據沒有對齊時,須要填充來補全。)
對象的定位:框架
- 使用句柄
- 優勢 :對象被移動 只會改變句柄中的的指針
- 缺點 :多了一次查找
- 直接指針訪問 (√)
OutOfMemoryError
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;jvm
內存泄露 memory leak,是指程序在申請內存後,沒法釋放已申請的內存空間,一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光。佈局
StackOverflowError
- 若是線程申請的棧的深度大於虛擬機所容許的最大深度,拋出StackOverflowError異常
- 若是虛擬機在擴展棧時候,沒法申請到足夠的內存空間。拋出OutOfMemory異常
方法區與運行時常量溢出
- jdk 1.6 以及以前的版本可使用 String.intern() 方法
- String.intern() 方法的是做用是:若是字符串常量池中已經含有此字符串那麼返回此字符串的,若是不包含此字符串 那麼將此 字符串實例 複製到字符串常量池中。
- jdk 1.7 版本不會將字符串 複製 字符串實例,只會記錄此字符串的引用。
- jdk 1.7 只會可使用 反射,或者字節碼操做框架產生大量的Class對象來形成 方法區溢出
本地直接內存溢出 -XX:MaxDirectMemorySize=10M;
若是發生了內存溢出異常,可是dump文件看不出明顯的異常,而且dump文件很小,而程序中又直接或者間接使用了NIO,那麼能夠考慮檢查是否是這一方面的問題線程