一:運行時數據區
1.這當中線程 共享和線程私有:
01.線程共享:
堆, 方法區
02.線程私有
虛擬機棧,本地方法棧,程序計數器
程序計數器:
在計算機操作系統中程序計數器表示這個程序要執行的下一個指令的地址,對於JVM中的程序計數器可以看做是當前線程所執行的字節碼的
行號指示器,每個線程都有一個程序計數器(當線程都在執行的時候,如果線程要切換將要保證線程回歸到正確的位置),重要的一點——
程序計數器,這是JVM規范中唯一一個沒有規定會導致
OutOfMemory(內存泄露,下文簡稱OOM)的區域。
虛擬機棧:
基本數據類型的變量和對象的引用變量都存在此區域;
遵循“
先進后出,
后進先出”的原則;
這塊區域可能會拋出StackOverflowError或者OOM錯誤。設置JVM參數”-Xss228k”(棧大小為228k)。
StackOverflowError:
線程請求的棧深度大於了虛擬機規定的最大深度;
OutOfMemoryError:
虛擬機在擴展棧時,無法申請到足夠的內存空間,
本地方法棧:
在Hotspot中
虛擬機棧和本地方法棧合為一體,
堆:
所有對象的實力和數組開辟的空間都在此區域保存;
所有線程共享;
GC主要回收對象的區域;
堆分區:
新生代
老年代
永久代
方法區:(靜態區)
所有線程共享;
方法(包含構造函數),接口 定義在此區域;
所有方法的信息;
存放靜態變量+常量+類信息+方法信息+常量池;
常量池中存放程序在編譯期間生成的各種變量以及符號引用
二:生命周期
類的生命周期從類被加載,連接和初始化開始
到類的卸載結束
01.類的生命周期中,類的的2進制數據位於方法區
02.在堆區會有一個描述的Class對象
類的加載: 需要類加載器
將Class字節碼文件內容加載到內存中,並將這些靜態數據轉化成法區中運行時數據結構!
在堆中生成一個Class對象;這個Class對象就是方法區類數據的訪問入ロ
類的連接:
驗證: 在編譯期間
類結構檢查
語義檢查 語法檢查
字節碼驗證 確保jvm認識
准備
為static修飾的賦初始值
類的解析
將符號引用轉變成直接引用
初始化
加載不是初始化 初始化指的是實例化!
創建出類的實例初始化的時機
1. 類的主動引用
new—個類的對象
通過反射的 newinstance()
再初始化子類的時候必須先初始化父類
2. 類的被動引用
通過類名訪問靜態的內容
調用類的靜態常量也不會初始化類
用類作為對象數組存在時,也不會初始化類
子類調用父類的靜態變量不會加載子類的靜態代碼塊(不會執行類的准備
類被主動引用的時候會被初始化
在被動引用的時候不會
三:垃圾回收機制(GC)
3.1:為什么需要垃圾回收機制
01.只要是對象被創建,那么就會在虛擬機的堆中開辟空間;
02.程序運行過程中會創建N個對象,每個對象都會有自己的空間;
03.如果每個對象都永久占用這塊內存空間,顯然內存是不夠的;
為了保證其他的對象能夠被正確的創建;
在C語言中,垃圾回收機制的任務是程序員自身負責;
可能出現的問題:
01.由於程序員大意,導致沒有及時釋放不適應的對象,釋放錯誤;
02.程序員一旦釋放程序核心的對象,可能會導致系統崩潰;
3.2:垃圾回收機制的定義
在java程序運行過程中,jvm中有一個專門負責回收那些不在使用的對象所占用的內存;
這種回收的過程,我們稱之為垃圾回收機制(GC);
3.3:垃圾回收機制的特點
01.減輕了程序員進行內存管理的負擔;
02.防止系統內存被非法釋放,是我們的程序更加健壯;
03.只有在對象不被任何變量引用的時候,才會被回收;
04.程序無法強制讓垃圾回收機制立即回收垃圾操作;
05.當垃圾回收器要回收不用對象的內存時會先調用這個對象的finalize()
這個方法有可能回事對象復活,導致垃圾回收機制取消對該對象的回收。
3.4 :對象的狀態
在java虛擬機的垃圾回收器來看,堆中所有的對象都有3種狀態!
01.可觸及狀態
02.可復活狀態
03.不可觸及狀態
只有對象處於不可觸及狀態的時候,垃圾回收期才會真正的釋放對象所占有的內存!
1.對象的生命周期開始( new語句或者是反射中newInstance ) 可觸及狀態
2.對象不在被引用,或者對象調用了finalize() 可復活狀態
3.對象調用了finalize() 不可觸及狀態
4.垃圾回收
5對象的生 命周期結束
3.5 :垃圾何時被回收(觸發GC的條件)
01.對象沒有引用===》對象處於不可觸及狀態
02.程序在作用域正常執行完畢之后
03. System. exit()
04.程序以外終止
3.6 :詳解GC
01.什么時間=== )觸發GC的條件
001. System. gc( )可能觸發;
002.系統自身決定GC的觸發時機
根據Eden區和From Space區的內存大小來決定!
02.對什么東西
java中的對象=== )通過分析算法無法找到的對象
03.做了什么
對搜索到的對象進行復制操作;
對搜索不到的對象執行finalize()。
如果真正的回收一個對象,要至少需要兩次標記!
01.第一次標記:對於一個沒有其他對象引用的時候;執行finalize()
02.第次標記:針對於篩選過的對象, 進行回收。
3.7 : java中內存分配機制
核心:分代分配,分代回收!
新生代(Young Generation)
Eden 區 :是連續的內存空間,所以分配內存極快
Survivor區 :From To必須有一個區域是空的
老年代(old Generation)
永久代(Permanet Generation)
注意點:
01.絕大多數創建的對象被分配在Eden區,但是大多數對象會在這個區域死亡!
02.當Eden區滿的時候,會執行Minor GC,將死亡的對象清理掉
3.7 : java中內存分配機制
核心:分代分配,分代回收!
新生代(Young Generation)
Eden 區 :是連續的內存空間,所以分配內存極快Survivor區 From To必須有一個區域是空的=
老年代(old Generation)
永久代(Permanet Generation) ===》方法區
回收兩種數據:
01.常量池中的常量
02.無用的類信息
什么時候回收?
01.類所有的實例都被回收了
02.加載類的ClassLoader也被回收了03.類對應的Class對象沒有被引用
注意點:
01.絕大多數創建的對象被分配在Eden區,但是大多數對象會在這個區域死亡!
02.當Eden區滿的時候,會執行Minor GC(Young GC) ,將死亡的對象清理掉,
剩余存活的對象存放到survivore區(survivor1區必然為空)
03.以后每次Eden區滿的時候,會執行Minor GC,所有存活的對象又被放進survivor0區
04.當survivor0區滿的時候,會把存活的對象復制到survivor1區,之后清空survivore區!
05.反復執行之后,仍然活着的對象復制到老年代!
06.老年代的內存比年輕代要大,但是也有滿的時候,當老年代滿的時候執行Major GC(Fu1l GC)
07.如果對象比較大,年輕代存放不下,就會直接把對象放進老年代!
Young GC和Fu11 GC的區別:
01. Young GC是在新生代的Eden區滿,Survivor區 滿的時候觸發
Full GC是在老年代滿的時候觸發
02. Young GC執行的頻率高
Full GC執行的頻率低
什么時候觸發Full GC
01.執行System. gc(),系統建議執行Full GC,但不是必須執行
02.老年代空間不足
001.當Young GC執行后存活的對象需要進駐老年代,但是發現老年代空間不足
002.當Survivore區,Survivor1區來回切換時,發現內存不足,必須放進老年代,而且老年代空間不足
03.方法區空間不足
3.8:GC涉及到的算法
01.引用計數法 Refernce Counting
給對象增加一個引用計數器,使用一次引用+1,少一個引用-1;
當引用為0的時候回收;
但是不能解決循環引用的問題;
02.根搜索算法
對象以根作為起點,向下延伸,延伸的路徑我們稱為 引用鏈
當一個對象沒有任何引用鏈鏈接的時候,證明這個對象是不可用對象(不可達),會被回收;
什么是根?
01.方法區中常量引用的對象
02.棧中引用的對象
03.靜態屬性引用的對象
03.復制算法Copying

就是將原有的內存空間分為兩塊,每次只能使用其中一塊!
缺點就是浪費一半的內存空間!比標記清除算法要高效!
不適合存活對象較多的區域使用!在新生代使用!
04.標記清除算法Mark -Sweep

001把所有存活的對象打個標記
002 .把所有沒有標記的對象統一清除
缺點:
01.兩個過程效率都慢,因為需要想查詢
02.因為在清除過程中會產生內存碎片,如果有大對象將無法存儲
04.標記一整理算法Mark Compact

適合存活對象多的區域,所以適合在老年代使用!
總結沒有了,看到這行留個言,,