說起內存我們要先了解JAVA虛擬機
JAVA虛擬機
java虛擬機在運行程序時會在內存空間分配一塊區域用於程序的運行,虛擬機又會把這一塊區域劃分爲若干個不同的數據塊
線程私有:程序計數器、虛擬機棧、本地方法棧;
共享數據區:方法區、java堆。
程序計數器相當於一個執行代碼的指示器,用來確認下一行執行代碼的地址,每個線程都有一個,沒有OOM的區。
虛擬機棧:我們平常所說的棧就是指這一塊區域,虛擬機規範中定義了OOM和stackoverflow異常。
本地方法棧:java虛擬機規範中定義了OOM和stackoverflow異常。
在hotspotVM(Sun JDK虛擬機)把虛擬機棧和本地方法棧合爲一個棧區。
方法區:分配給ClassLoader加載類信息,常量,靜態變量,編譯後的代碼。
堆區:分配給對象實例和數組,是虛擬機管理的最大的一塊內存,是GC的主戰場。
GC垃圾回收器
GC如何確定內存回收:
1、引用計數算法
就是對象在引用一次計數+1,置空時-1,只有計數爲0時進行回收,其缺點也很明顯,就是互相引用時計數永不爲0。
2、可達性分析算法
當一個對象到GC Root沒有任何引用鏈相連時(即從GC Roots節點到該節點不可達),則證明該對象是不可用的。
3、引用類型
強引用:不會主動被回收。
軟引用(SoftReference):內存不足時回收,存放一些重要性不是很強又不能隨便讓清除的對象,比如圖片切換到後臺不需要馬上顯示了。
弱引用(WeakReference):第一次掃到了,就標記下來,第二次掃到直接回收。
虛引用(PhantomReference):幽靈幻影引用 不對生存造成任何影響,用於跟蹤GC的回收通知
內存泄漏
產生原因:一個長生命週期的對象持有一個短生命週期對象的引用,通俗講就是該回收的對象,因爲引用問題沒有被回收,最終會產生OOM。