Java 的自動內(nèi)存管理主要是針對對象內(nèi)存的回收和對象內(nèi)存的分配
(資料圖片僅供參考)
當 Eden 區(qū)沒有足夠空間進行分配時
大對象直接進入老年代,大對象就是需要大量連續(xù)內(nèi)存空間的對象。大對象直接進入老年代主要是為了避免為大對象分配內(nèi)存時由于分配擔保機制帶來的復制而降低效率
長期存活的對象將進入老年代
回收機制:
部分收集 (Partial GC):
新生代收集(Minor GC / Young GC):只對新生代進行垃圾收集整堆收集 (Full GC):收集整個 Java 堆和方法區(qū)。
GC 調(diào)優(yōu)策略中很重要的一條經(jīng)驗總結是這樣說的:
將新對象預留在新生代
引用計數(shù)法:給對象中添加一個引用計數(shù)器:有一個地方引用它
可達性分析算法:通過一系列的稱為 “GC Roots”的對象作為起點
對象可以被回收,就代表一定會被回收嗎 即使在可達性分析法中不可達的對象,也并非是“非死不可”的 1.強引用(StrongReference) 一個對象具有強引用 2.軟引用(SoftReference) 如果一個對象只具有軟引用,那就類似于可有可無的生活用品 3.弱引用(WeakReference) 如果一個對象只具有弱引用,那就類似于可有可無的生活用品 4.虛引用(PhantomReference) 與其他幾種引用都不同 虛引用與軟引用和弱引用的一個區(qū)別在于:虛引用必須和引用隊列(ReferenceQueue)聯(lián)合使用。當垃圾回收器準備回收一個對象時 運行時常量池主要回收的是廢棄的常量。 字符串常量池中存在字符串 "abc" 方法區(qū)主要回收的是無用的類 標記-清除算法:該算法分為“標記”和“清除”階段:首先標記出所有不需要回收的對象,在標記完成后統(tǒng)一回收掉所有沒有被標記的對象 標記-復制算法:將內(nèi)存分為大小相同的兩塊 標記-整理算法:根據(jù)老年代的特點提出的一種標記算法 分代收集算法:當前虛擬機的垃圾收集都采用分代收集算法,根據(jù)對象存活周期的不同將內(nèi)存分為幾塊 比如在新生代中,每次收集都會有大量對象死去,所以可以選擇”標記-復制“算法,只需要付出少量對象的復制成本就可以完成每次垃圾收集。而老年代的對象存活幾率是比較高的,而且沒有額外的空間對它進行分配擔保,所以我們必須選擇“標記-清除”或“標記-整理”算法進行垃圾收集。 Serial (串行)收集器:最基本 ParNew 收集器:Serial 收集器的多線程版本 Parallel Scavenge 收集器:收集器關注點是吞吐量(高效率的利用 CPU) 上面都是新生代采用標記-復制算法 Serial Old 收集器:Serial 收集器的老年代版本,它同樣是一個單線程收集器 Parallel Old 收集器:Parallel Scavenge 收集器的老年代版本 CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。它非常符合在注重用戶體驗的應用上使用。是 HotSpot 虛擬機第一款真正意義上的并發(fā)收集器,它第一次實現(xiàn)了讓垃圾收集線程與用戶線程(基本上)同時工作