1. 程式人生 > >jvm的新生代、老年代、永久代關係

jvm的新生代、老年代、永久代關係

原文地址:https://blog.csdn.net/iechenyb/article/details/79424974

新生代分為三個區域,一個Eden區和兩個Survivor區,它們之間的比例為(8:1:1),這個比例也是可以修改的。通常情況下,物件主要分配在新生代的Eden區上,少數情況下也可能會直接分配在老年代中。Java虛擬機器每次使用新生代中的Eden和其中一塊Survivor(From),在經過一次Minor GC後,將Eden和Survivor中還存活的物件一次性地複製到另一塊Survivor空間上(這裡使用的複製演算法進行GC),最後清理掉Eden和剛才用過的Survivor(From)空間。將此時在Survivor空間存活下來的物件的年齡設定為1,以後這些物件每在Survivor區熬過一次GC,它們的年齡就加1,當物件年齡達到某個年齡(預設值為15)時,就會把它們移到老年代中。

在新生代中進行GC時,有可能遇到另外一塊Survivor空間沒有足夠空間存放上一次新生代收集下來的存活物件,這些物件將直接通過分配擔保機制進入老年代;


1.Eden區

    Eden區位於Java堆的年輕代,是新物件分配記憶體的地方,由於堆是所有執行緒共享的,因此在堆上分配記憶體需要加鎖。而Sun JDK為提升效率,會為每個新建的執行緒在Eden上分配一塊獨立的空間由該執行緒獨享,這塊空間稱為TLAB(Thread Local Allocation Buffer)。在TLAB上分配記憶體不需要加鎖,因此JVM在給執行緒中的物件分配記憶體時會盡量在TLAB上分配。如果物件過大或TLAB用完,則仍然在堆上進行分配。如果Eden區記憶體也用完了,則會進行一次Minor GC(young GC)。

2.Survival from to

    Survival區與Eden區相同都在Java堆的年輕代。Survival區有兩塊,一塊稱為from區,另一塊為to區,這兩個區是相對的,在發生一次Minor GC後,from區就會和to區互換。在發生Minor GC時,Eden區和Survivalfrom區會把一些仍然存活的物件複製進Survival to區,並清除記憶體。Survival to區會把一些存活得足夠舊的物件移至年老代。

3.年老代

    年老代裡存放的都是存活時間較久的,大小較大的物件,因此年老代使用標記整理演算法。當年老代容量滿的時候,會觸發一次Major GC(full GC),回收年老代和年輕代中不再被使用的物件資源。


總結:

1、Minor GC是發生在新生代中的垃圾收集,採用的複製演算法;

2、新生代中每次使用的空間不超過90%,主要用來存放新生的物件;

3、Minor GC每次收集後Eden區和一塊Survivor區都被清空;

4、老年代中使用Full GC,採用的標記-清除演算法

注意:

堆=新生代+老年代,不包括永久代(方法區)。

很多人認為方法區(或者HotSpot虛擬機器中的永久代)是沒有垃圾收集的,Java虛擬機器規範中確實說過可以不要求虛擬機器在方法區實現垃圾收集,而且在方法區進行垃圾收集的“價效比”一般比較低:在堆中,尤其是在新生代中,常規應用進行一次垃圾收集一般可以回收70%~95%的空間,而永久代的垃圾收集效率遠低於此。

永久代的垃圾收集主要回收兩部分內容:廢棄常量和無用的類。回收廢棄常量與回收Java堆中的物件非常類似。以常量池中字面量的回收為例,假如一個字串“abc”已經進入了常量池中,但是當前系統沒有任何一個String物件是叫做“abc”的,換句話說是沒有任何String物件引用常量池中的“abc”常量,也沒有其他地方引用了這個字面量,如果在這時候發生記憶體回收,而且必要的話,這個“abc”常量就會被系統“請”出常量池。常量池中的其他類(介面)、方法、欄位的符號引用也與此類似。

判定一個常量是否是“廢棄常量”比較簡單,而要判定一個類是否是“無用的類”的條件則相對苛刻許多。類需要同時滿足下面3個條件才能算是“無用的類”:

該類所有的例項都已經被回收,也就是Java堆中不存在該類的任何例項。

載入該類的ClassLoader已經被回收。

該類對應的java.lang.Class 物件沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。

虛擬機器可以對滿足上述3個條件的無用類進行回收,這裡說的僅僅是“可以”,而不是和物件一樣,不使用了就必然會回收。是否對類進行回收,HotSpot虛擬機器提供了-Xnoclassgc引數進行控制,還可以使用-verbose:class及-XX:+TraceClassLoading、 -XX:+TraceClassUnLoading檢視類的載入和解除安裝資訊。

在大量使用反射、動態代理、CGLib等bytecode框架的場景,以及動態生成JSP和OSGi這類頻繁自定義ClassLoader的場景都需要虛擬機器具備類解除安裝的功能,以保證永久代不會溢位。

相關推薦

JVM新生代年代永久的理解

新生代、老年代、永久代 一般把java堆分為新生代、老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法。新生代中,每次垃圾收集時都發現大批物件死去,只有少量物件存活,便採用了複製演算法,只需要付出少量存活物件的複製成本就可以完成收集。而老年代中因為物件存活率高、沒有額外空間對它進行

JVM記憶體管理JVM垃圾回收機制新生代年代以及永久

     如果大家想深入的瞭解JVM,可以讀讀周志明《深入理解Java虛擬機器:JVM高階特性與最佳實踐》      需要掌握的東西,包括以下內容、判斷物件存活還是死亡的演算法(引用計數演算法、可達性分析演算法)、常見的垃圾收集演算法(複製演算法、分代收集演算法等以及這

(入門貼)JVM堆記憶體相關的啟動引數:年輕年代永久的記憶體分配

如果想觀察JVM程序佔用的堆記憶體,可以通過命令工具jmap或者視覺化工具jvisualvm.exe。JVM這些啟動引數都擁有預設值,如果想了解JVM的記憶體分配策略,最好手動設定這些啟動引數。再通過

jvm新生代年代永久關係

原文地址:https://blog.csdn.net/iechenyb/article/details/79424974新生代分為三個區域,一個Eden區和兩個Survivor區,它們之間的比例為(8:1:1),這個比例也是可以修改的。通常情況下,物件主要分配在新生代的Ede

JVM內存:年輕年代永久(推薦 轉)

回收 以及 平靜的 保持 size 個人 對象更新 you 應用 參考文章: 1.Java 新生代、老年代、持久代、元空間 2.Java內存與垃圾回收調優 3.方法區的Class信息,又稱為永久代,是否屬於Java堆? Java 中的堆是 JVM 所管理的最大的一塊內存空

根據應用程式設定JVM引數(一)-設定堆新生代年代持久大小

一、根據程式的執行狀況檢視其活躍的資料量 ①、活躍的資料: 1.應用程式運行於穩定狀態時,老年代佔用的java堆大小 2.應用程式運行於穩定狀態時,永久代佔用的java堆大小 其實就是FullGc後這2個數據的大小 ②、動手測試:1.測試程式碼: public cl

JVM垃圾收集器(一) —— 概念:新生代年代並行和併發

在上篇文章中我們講到了垃圾回收的幾種演算法。垃圾收集演算法是記憶體回收的方法論,而垃圾收集器是垃圾回收的具體實現。 在瞭解垃圾收集器之前,本篇文章先來簡單的說一下新生代和老年代、並行和併發的概念。 新生代和老年代 從記憶體回收的角度來看,一般我們可以將Java堆分

JVM記憶體:年輕年代永久

Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用於存放各種類的例項物件,如下圖所示:  在 Java 中,堆被劃分成兩個不同的區域:新生代 ( Young )、老年代 ( Old)。新生代 ( Young ) 又被劃分為三個區域:Eden、S0、S1。 這樣劃分的目的是

jvm裡面年輕年代永久,元空間

1.年輕代 年輕代主要有三個區域組成,一個是Eden區域,另一個是存活區1和存活區2。Eden主要負責物件的建立,存活區1和存活2主要負責向老年代普及物件,存活區1和存活區2這兩個區域裡面總存在一個是空的,為什麼這兩個區域裡面有一個空的呢?因為這兩個區域需要負責回收年輕代活躍物件,需要把這些年輕

年輕年代GC原理詳細拆解

1、為什麼要對堆記憶體分代     我們先來屢屢,為什麼需要把堆分代?不分代不能完成他所做的事情麼?其實不分代完全可以,分代的唯一理由就是優化GC效能。你先想想,如果沒有分代,那我們所有的物件都在一塊,GC的時候我們要找到哪些物件沒用,這樣就會對堆的所有區域進行掃描。而我們的

JVM年輕年代永久詳解

前言 最近被問到了這個問題,解釋的不是很清晰,有一些概念略微模糊,在此進行整理和記錄,分享給大家。本篇文章主要講解記憶體區域的年輕代,老年代和永久代,略微提及一些垃圾回收演算法,下面是正文。 堆整體 堆主要用於存放各種類的例項物件和陣列。在java中被分為兩個區域:年輕代和老年代。在java中還有一個永久

深入理解Java虛擬機器(四)EdenSurvivor年代GC日誌

1. 年輕代 1.1 Eden區和Survivor區 新生代GC(Minor GC):指發生在新生代的垃圾收集動作,Minor GC非常頻繁,新生代採用複製演算法,一般回收速度也比較快。因為採用複製演算法,所以年輕代分為三部分:1個Eden區和2個Survivor區(分別叫Fro

深入JVM 原理(七)年代永久和元空間

目錄 老年代 老年代主要接收由年輕代傳送過來的物件,一般情況下,經過了數次Minor GC 之後還會儲存下來的物件才會進入到老年代。如果要儲存的物件超過了伊甸園區的大小,此物件也將直接儲存在老年代之中,當老年代記憶體不足時,將引發 “major GC”,

JVM中的新生代年代(Eden空間兩個Survior空間)

現有的主流JVM分別是HotSpot和JRockit,主要研究物件也是這兩個。這篇文章裡,我們只研究HotSpot,也就是所謂的Sun JVM。目前階段,Sun的GC方式主要有CMS和G1兩種。考慮到效果和實際應用,這裡只介紹CMS。CMS,全稱Concurrent Low

java GC 棧(虛擬機器棧,本地方法棧),堆(新生代年代), 方法區(永久帶)等引數配置

-Xms 初始堆大小。如:-Xms256m -Xmx 最大堆大小。如:-Xmx512m -Xmn 新生代大小。通常為 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 個 Su

java虛擬機器JVM--java虛擬機器的記憶體管理(新生代年代

前言 在上一篇部落格中,還遺留了一個問題:JVM的記憶體如何分配最高效?換一種說法就是:JVM的記憶體是如何的分配以及回收的?通過前面兩篇部落格的鋪墊:java虛擬機器JVM–java虛擬機器的結構, java虛擬機器JVM–java虛擬機器垃圾的回收機制詳解

Java GC新生代年代

堆記憶體                                                                                  Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用於存放各種類的例項物件。 在

GC日誌分析年輕年代

堆記憶體 Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用於存放各種類的例項物件。 在 Java 中,堆被劃分成兩個不同的區域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被劃分為三個區域:Eden、From Sur

Java GC新生代年代過程

存                                                                                  Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用於存放各種類的例項物件。 在 Java

Java堆空間的劃分:新生代年代

預設Eden:S0:S1=8:1:1,因此,新生代中可以使用的記憶體空間大小佔用新生代的9/10,那麼有人就會問,為什麼不直接分成兩個區,一個區佔9/10,另一個區佔1/10,這樣做的原因大概有以下幾種  1.S0與S1的區間明顯較小,有效新生代空間為Eden+S0/S1,因此有效空間就大,增加了記憶體使用率