日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《深入理解java虚拟机》笔记2——GC算法与内存分配策略

發(fā)布時(shí)間:2025/3/21 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《深入理解java虚拟机》笔记2——GC算法与内存分配策略 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM實(shí)現(xiàn)里非常重要的一環(huán),JVM成熟的內(nèi)存動(dòng)態(tài)分配與回收技術(shù)使Java(當(dāng)然還有其他運(yùn)行在JVM上的語言,如Scala等)程序員在提升開發(fā)效率上獲得了驚人的便利。理解GC,對(duì)于理解JVM和Java語言有著非常重要的作用。并且當(dāng)我們需要排查各種內(nèi)存溢出、內(nèi)存泄漏問題時(shí),當(dāng)垃圾收集稱為系統(tǒng)達(dá)到更高并發(fā)量的瓶頸時(shí),只有深入理解GC和內(nèi)存分配,才能對(duì)這些“自動(dòng)化”的技術(shù)實(shí)施必要的監(jiān)控和調(diào)節(jié)。

在Java的運(yùn)行時(shí)數(shù)據(jù)區(qū)中,程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧三個(gè)區(qū)域都是線程私有的,隨線程而生,隨線程而滅,在方法結(jié)束或線程結(jié)束時(shí),內(nèi)存自然就跟著回收了,不需要過多考慮回收的問題。而Java堆方法區(qū)則不一樣,一個(gè)接口中的多個(gè)實(shí)現(xiàn)類需要的內(nèi)存可能不一樣,一個(gè)方法中的多個(gè)分支需要的內(nèi)存也可能不一樣,我們只有在程序處于運(yùn)行期間才能知道會(huì)創(chuàng)建哪些對(duì)象,這部分內(nèi)存的分配和回收都是動(dòng)態(tài)的,垃圾回收器關(guān)注的是這部分內(nèi)存,后續(xù)討論的“內(nèi)存”分配回收也是指這一塊,尤其需要注意。

GC主要回答了以下三個(gè)問題:

  • 哪些內(nèi)存需要回收?
  • 什么時(shí)候回收?
  • 如何回收?

這三個(gè)問題的具體解決方案,也就是本文接下來要講解的內(nèi)容。

對(duì)象已死嗎?

在堆里存放著Java世界中幾乎所有的對(duì)象實(shí)例,垃圾收集器在對(duì)堆進(jìn)行回收前,首要的就是確定這些對(duì)象中哪些還“存活”著,哪些已經(jīng)“死去”(即不可能再被任何途徑使用的對(duì)象)。

引用計(jì)數(shù)算法

引用計(jì)數(shù)算法是在JVM中被摒棄的一種對(duì)象存活判定算法,不過它也有一些知名的應(yīng)用場景(如Python、FlashPlayer),因此在這里也簡單介紹一下。

用引用計(jì)數(shù)器判斷對(duì)象是否存活的過程是這樣的:給對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器加1;當(dāng)引用失效時(shí),計(jì)數(shù)器減1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。

引用計(jì)數(shù)算法的實(shí)現(xiàn)簡單,判定效率也很高,大部分情況下是一個(gè)不錯(cuò)的算法。它沒有被JVM采用的原因是它很難解決對(duì)象之間循環(huán)引用的問題。例如以下例子:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /*** testGC()方法執(zhí)行后,objA和objB會(huì)不會(huì)被GC呢? */ public class ReferenceCountingGC {public Object instance = null;private static final int _1MB = 1024 * 1024;/*** 這個(gè)成員屬性的唯一意義就是占點(diǎn)內(nèi)存,以便在能在GC日志中看清楚是否有回收過*/private byte[] bigSize = new byte[2 * _1MB];public static void testGC() {ReferenceCountingGC objA = new ReferenceCountingGC();ReferenceCountingGC objB = new ReferenceCountingGC();objA.instance = objB;objB.instance = objA;objA = null;objB = null;// 假設(shè)在這行發(fā)生GC,objA和objB是否能被回收?System.gc();} }

在上面這段代碼中,對(duì)象objA 和對(duì)象objB都有字段instance,賦值令objA.instance = objB;、objB.instance = objA;,除此之外,這兩個(gè)對(duì)象再無引用。如果JVM采用引用計(jì)數(shù)算法來管理內(nèi)存,這兩個(gè)對(duì)象不可能再被訪問,但是他們互相引用著對(duì)方,導(dǎo)致它們引用計(jì)數(shù)不為0,所以引用計(jì)數(shù)器無法通知GC收集器回收它們。

而事實(shí)上執(zhí)行這段代碼,objA和objB是可以被回收的,下面一節(jié)將介紹JVM實(shí)際使用的存活判定算法。

可達(dá)性分析算法

在主流商用程序語言的實(shí)現(xiàn)中,都是通過可達(dá)性分析(tracing GC)來判定對(duì)象是否存活的。此算法的基本思路是:通過一系列的稱為“GC Roots”的對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連(用圖論的話來說,就是GC Roots 到這個(gè)對(duì)象不可達(dá))時(shí),則證明此對(duì)象時(shí)不可用的。用下圖來加以說明:

?

上圖中,對(duì)象object 5、object 6、object 7雖然互有關(guān)聯(lián),但是它們到GC Roots是不可達(dá)的,所以它們將會(huì)被判定為是可回收的對(duì)象。

?

可以看到,GC Roots在對(duì)象圖之外,是特別定義的“起點(diǎn)”,不可能被對(duì)象圖內(nèi)的對(duì)象所引用。

準(zhǔn)確地說,GC Roots其實(shí)不是一組對(duì)象,而通常是一組特別管理的指向引用類型對(duì)象的指針,這些指針是tracing GC的trace的起點(diǎn)。它們不是對(duì)象圖里的對(duì)象,對(duì)象也不可能引用到這些“外部”的指針,這也是tracing GC算法不會(huì)出現(xiàn)循環(huán)引用問題的基本保證。因此也容易得出,只有引用類型的變量才被認(rèn)為是Roots,值類型的變量永遠(yuǎn)不被認(rèn)為是Roots。只有深刻理解引用類型和值類型的內(nèi)存分配和管理的不同,才能知道為什么root只能是引用類型。

在Java中,可作為GC Roots的對(duì)象包括以下幾種:

  • 虛擬機(jī)棧(棧幀中的局部變量表,Local Variable Table)中引用的對(duì)象。
  • 方法區(qū)中類靜態(tài)屬性引用的對(duì)象。
  • 方法區(qū)中常量引用的對(duì)象。
  • 本地方法棧中JNI(即一般說的Native方法)引用的對(duì)象。

看到這里你可能要問,選擇這些對(duì)象的依據(jù)是什么呢?

可以概括得出,可作為GC Roots的節(jié)點(diǎn)主要在全局性的引用執(zhí)行上下文中。要明確的是,tracing gc必須以當(dāng)前存活的對(duì)象集為Roots,因此必須選取確定存活的引用類型對(duì)象。GC管理的區(qū)域是Java堆,虛擬機(jī)棧、方法區(qū)本地方法棧不被GC所管理,因此選用這些區(qū)域內(nèi)引用的對(duì)象作為GC Roots,是不會(huì)被GC所回收的。其中虛擬機(jī)棧和本地方法棧都是線程私有的內(nèi)存區(qū)域,只要線程沒有終止,就能確保它們中引用的對(duì)象的存活。而方法區(qū)中類靜態(tài)屬性引用的對(duì)象是顯然存活的。常量引用的對(duì)象在當(dāng)前可能存活,因此,也可能是GC roots的一部分。

再談引用

無論是通過引用計(jì)數(shù)算法判斷對(duì)象的引用數(shù)量,還是通過可達(dá)性分析算法判斷對(duì)象是否可達(dá),判定對(duì)象是否可被回收都與引用有關(guān)。在JDK1.2之前,Java中的應(yīng)用定義跟很傳統(tǒng),如若reference類型的數(shù)據(jù)引用了一塊內(nèi)存地址,則這塊內(nèi)存代表一個(gè)引用,這樣一個(gè)對(duì)象僅有被引用或沒有被引用兩種狀態(tài),對(duì)于一些“食之無味,棄之可惜”的無法描述。

JDK1.2之后,Java 提供了四種強(qiáng)度不同的引用類型。

強(qiáng)引用

被強(qiáng)引用關(guān)聯(lián)的對(duì)象不會(huì)被回收。

使用 new 一個(gè)新對(duì)象的方式來創(chuàng)建強(qiáng)引用。

1 Object obj = new Object();

軟引用

被軟引用關(guān)聯(lián)的對(duì)象只有在內(nèi)存不夠的情況下才會(huì)被回收。

使用 SoftReference 類來創(chuàng)建軟引用。

1 2 3 Object obj = new Object(); SoftReference<Object> sf = new SoftReference<Object>(obj); obj = null; // 使對(duì)象只被軟引用關(guān)聯(lián)

弱引用

被弱引用關(guān)聯(lián)的對(duì)象一定會(huì)被回收,也就是說它只能存活到下一次垃圾回收發(fā)生之前。

使用 WeakReference 類來實(shí)現(xiàn)弱引用。

1 2 3 Object obj = new Object(); WeakReference<Object> wf = new WeakReference<Object>(obj); obj = null;

虛引用

又稱為幽靈引用或者幻影引用。一個(gè)對(duì)象是否有虛引用的存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無法通過虛引用取得一個(gè)對(duì)象。

為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被回收時(shí)收到一個(gè)系統(tǒng)通知。

使用 PhantomReference 來實(shí)現(xiàn)虛引用。

1 2 3 Object obj = new Object(); PhantomReference<Object> pf = new PhantomReference<Object>(obj); obj = null;

兩次標(biāo)記與 finalize()方法

即使在可達(dá)性分析算法中不可達(dá)的對(duì)象,也不是一定會(huì)死亡的,它們暫時(shí)都處于“緩刑”階段,要真正宣告一個(gè)對(duì)象“死亡”,至少要經(jīng)歷兩次標(biāo)記過程:

如果對(duì)象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒有與 GC Roots相連接的引用鏈,那它將會(huì)被第一次標(biāo)記并且進(jìn)行一次篩選,篩選的條件是此對(duì)象是否有必要執(zhí)行finaliza()方法。當(dāng)對(duì)象沒有覆蓋finaliza()方法,或者finaliza()方法已經(jīng)被虛擬機(jī)調(diào)用過,虛擬機(jī)將這兩種情況都視為“沒有必要執(zhí)行”。

如果這個(gè)對(duì)象被判定為有必要執(zhí)行finaliza()方法,那么此對(duì)象將會(huì)放置在一個(gè)叫做 F-Queue 的隊(duì)列中,并在稍后由一個(gè)虛擬機(jī)自動(dòng)建立的、低優(yōu)先級(jí)的Finalizer線程去執(zhí)行它。這里所謂的“執(zhí)行”是指虛擬機(jī)會(huì)觸發(fā)此方法,但并不承諾會(huì)等待它運(yùn)行結(jié)束,原因是:如果一個(gè)對(duì)象在finaliza()方法中執(zhí)行緩慢,或者發(fā)生了死循環(huán)(更極端的情況),將很可能導(dǎo)致F-Queue 隊(duì)列中的其它對(duì)象永久處于等待,甚至導(dǎo)致整個(gè)內(nèi)存回收系統(tǒng)崩潰。

finaliza()方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì),稍后GC將對(duì)F-Queue 隊(duì)列中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記。如果對(duì)象想在finaliza()方法中成功拯救自己,只要重新與引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián)即可,例如把自己(this關(guān)鍵字)賦值給某個(gè)類變量或者對(duì)象的成員變量,這樣在第二次標(biāo)記時(shí)它將被移出“即將回收”的集合;如果對(duì)象這時(shí)候還沒有逃脫,基本上它就真的被回收了。

值得注意的是,如果代碼中有兩段一模一樣的代碼段,執(zhí)行結(jié)果卻是一次逃脫成功,一次失敗。這是因?yàn)槿魏我粋€(gè)對(duì)象的finalize()方法都只會(huì)被系統(tǒng)調(diào)用一次,如果對(duì)象面臨下一次回收,它的finalize()方法不會(huì)再被執(zhí)行,因此第二次逃脫行動(dòng)失敗。

需要說明的是,使用finalize()方法來“拯救”對(duì)象是不值得提倡的,因?yàn)樗皇荂/C++中的析構(gòu)函數(shù),而是Java剛誕生時(shí)為了使C/C++程序員更容易接受它所做的一個(gè)妥協(xié)。它的運(yùn)行代價(jià)高昂,不確定性大,無法保證各個(gè)對(duì)象的調(diào)用順序。finalize()能做的工作,使用try-finally或者其它方法都更適合、及時(shí),所以筆者建議大家可以忘掉此方法存在。

回收方法區(qū)

很多人認(rèn)為方法區(qū)沒有垃圾回收,Java虛擬機(jī)規(guī)范中確實(shí)說過不要求,而且在方法區(qū)中進(jìn)行垃圾收集的“性價(jià)比”較低:在堆中,尤其是新生代,常規(guī)應(yīng)用進(jìn)行一次垃圾收集可以回收70%~95%的空間,而方法區(qū)的效率遠(yuǎn)低于此。在JDK 1.8中,JVM摒棄了永久代,用元空間來作為方法區(qū)的實(shí)現(xiàn),下面介紹的將是元空間的垃圾回收。

元空間的內(nèi)存管理由元空間虛擬機(jī)來完成。先前,對(duì)于類的元數(shù)據(jù)我們需要不同的垃圾回收器進(jìn)行處理,現(xiàn)在只需要執(zhí)行元空間虛擬機(jī)的C++代碼即可完成。在元空間中,類和其元數(shù)據(jù)的生命周期其對(duì)應(yīng)的類加載器是相同的。話句話說,只要類加載器存活,其加載的類的元數(shù)據(jù)也是存活的,因而不會(huì)被回收掉。

我們從行文到現(xiàn)在提到的元空間稍微有點(diǎn)不嚴(yán)謹(jǐn)。準(zhǔn)確的來說,每一個(gè)類加載器的存儲(chǔ)區(qū)域都稱作一個(gè)元空間,所有的元空間合在一起就是我們一直說的元空間。當(dāng)一個(gè)類加載器被垃圾回收器標(biāo)記為不再存活,其對(duì)應(yīng)的元空間會(huì)被回收。在元空間的回收過程中沒有重定位和壓縮等操作。但是元空間內(nèi)的元數(shù)據(jù)會(huì)進(jìn)行掃描來確定Java引用。

垃圾收集算法

本節(jié)將介紹幾種垃圾收集算法的思想及其發(fā)展過程,具體的實(shí)現(xiàn)將在稍后介紹。

標(biāo)記-清除(Mark-Sweep)算法

標(biāo)記-清除(Mark-Sweep)算法是最基礎(chǔ)的垃圾收集算法,后續(xù)的收集算法都是基于它的思路并對(duì)其不足進(jìn)行改進(jìn)而得到的。顧名思義,算法分成“標(biāo)記”、“清除”兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象,標(biāo)記過程在前一節(jié)講述對(duì)象標(biāo)記判定時(shí)已經(jīng)講過了。

標(biāo)記-清除算法的不足主要有以下兩點(diǎn):

  • 空間問題,標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對(duì)象時(shí),無法找到足夠的連續(xù)內(nèi)存而不得不觸發(fā)另一次垃圾收集動(dòng)作。
  • 效率問題,因?yàn)閮?nèi)存碎片的存在,操作會(huì)變得更加費(fèi)時(shí),因?yàn)椴檎蚁乱粋€(gè)可用空閑塊已不再是一個(gè)簡單操作。

標(biāo)記-清除算法的執(zhí)行過程如下圖所示:

?

?

復(fù)制(Copying)算法

為了解決標(biāo)記-清除算法的效率問題,一種稱為“復(fù)制”(Copying)的收集算法出現(xiàn)了,思想為:它將可用內(nèi)存按容量分成大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊內(nèi)存用完,就將還存活著的對(duì)象復(fù)制到另一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。

這樣做使得每次都是對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)也就不用考慮內(nèi)存碎片等復(fù)雜情況,只要移動(dòng)堆頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡單,運(yùn)行高效。只是這種算法的代價(jià)是將內(nèi)存縮小為原來的一半,代價(jià)可能過高了。復(fù)制算法的執(zhí)行過程如下圖所示:

?

Minor GC與復(fù)制算法

?

現(xiàn)在的商業(yè)虛擬機(jī)都使用復(fù)制算法來回收新生代。新生代的GC又叫“Minor GC”,IBM公司的專門研究表明:新生代中的對(duì)象98%是“朝生夕死”的,所以Minor GC非常頻繁,一般回收速度也比較快,同時(shí)“朝生夕死”的特性也使得Minor GC使用復(fù)制算法時(shí)不需要按照1:1的比例來劃分新生代內(nèi)存空間。

Minor GC過程

事實(shí)上,新生代將內(nèi)存分為一塊較大的Eden空間兩塊較小的Survivor空間(From Survivor和To Survivor)每次Minor GC都使用Eden和From Survivor,當(dāng)回收時(shí),將Eden和From Survivor中還存活著的對(duì)象都一次性地復(fù)制到另外一塊To Survivor空間上,最后清理掉Eden和剛使用的Survivor空間。一次Minor GC結(jié)束的時(shí)候Eden空間和From Survivor空間都是空的,而To Survivor空間里面存儲(chǔ)著存活的對(duì)象。在下次MinorGC的時(shí)候,兩個(gè)Survivor空間交換他們的標(biāo)簽,現(xiàn)在是空的“From” Survivor標(biāo)記成為“To”“To” Survivor標(biāo)記為“From”。因此,在MinorGC結(jié)束的時(shí)候,Eden空間是空的,兩個(gè)Survivor空間中的一個(gè)是空的,而另一個(gè)存儲(chǔ)著存活的對(duì)象。

HotSpot虛擬機(jī)默認(rèn)的Eden : Survivor的比例是8 : 1,由于一共有兩塊Survivor,所以每次新生代中可用內(nèi)存空間為整個(gè)新生代容量的90%(80%+10%),只有10%的容量會(huì)被“浪費(fèi)”。

分配擔(dān)保

上文說的98%的對(duì)象可回收只是一般場景下的數(shù)據(jù),我們沒有辦法保證每次回收都只有不多于10%的對(duì)象存活,當(dāng)Survivor空間不夠用時(shí),需要依賴老年代內(nèi)存進(jìn)行分配擔(dān)保(Handle Promotion)。如果另外一塊Survivor上沒有足夠空間存放上一次新生代收集下來的存活對(duì)象,這些對(duì)象將直接通過分配擔(dān)保機(jī)制進(jìn)入老年代。

標(biāo)記-整理(Mark-Compact)算法

復(fù)制算法在對(duì)象存活率較高時(shí)要進(jìn)行較多的復(fù)制操作,效率將會(huì)變低。更關(guān)鍵的是:如果不想浪費(fèi)50%的空間,就需要有額外的空間進(jìn)行分配擔(dān)保,以應(yīng)對(duì)被使用的內(nèi)存中所有對(duì)象都100%存活的極端情況,所以在老年代一般不能直接選用復(fù)制算法。

根據(jù)老年代的特點(diǎn),標(biāo)記-整理(Mark-Compact)算法被提出來,主要思想為:此算法的標(biāo)記過程與標(biāo)記-清除算法一樣,但后續(xù)步驟不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉邊界以外的內(nèi)存。具體示意圖如下所示:

?

?

分代收集(Generational Collection)算法

當(dāng)前商業(yè)虛擬機(jī)的垃圾收集都采用分代收集(Generational Collection)算法,此算法相較于前幾種沒有什么新的特征,主要思想為:根據(jù)對(duì)象存活周期的不同將內(nèi)存劃分為幾塊,一般是把Java堆分為新生代和老年代,這樣就可以根據(jù)各個(gè)年代的特點(diǎn)采用最適合的收集算法:

  • 新生代
    在新生代中,每次垃圾收集時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,只有少量存活,那就選用復(fù)制算法,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成收集。
  • 老年代
    在老年代中,因?yàn)閷?duì)象存活率高、沒有額外空間對(duì)它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記-清除”“標(biāo)記-整理”算法來進(jìn)行回收。

HotSpot的算法實(shí)現(xiàn)

前面兩大節(jié)主要從理論上介紹了對(duì)象存活判定算法和垃圾收集算法,而在HotSpot虛擬機(jī)上實(shí)現(xiàn)這些算法時(shí),必須對(duì)算法的執(zhí)行效率有嚴(yán)格的考量,才能保證虛擬機(jī)高效運(yùn)行。

枚舉根節(jié)點(diǎn)

從可達(dá)性分析中從GC Roots節(jié)點(diǎn)找引用鏈這個(gè)操作為例,可作為GC Roots的節(jié)點(diǎn)主要在全局性的引用(例如常量或類靜態(tài)屬性)與執(zhí)行上下文(例如棧幀中的局部變量表)中,現(xiàn)在很多應(yīng)用僅僅方法區(qū)就有數(shù)百兆,如果要逐個(gè)檢查這里面的引用,那么必然會(huì)消耗很多時(shí)間。

GC停頓(”Stop The World”)

另外,可達(dá)性分析工作必須在一個(gè)能確保一致性的快照中進(jìn)行——這里“一致性”的意思是指在整個(gè)分析期間整個(gè)執(zhí)行系統(tǒng)看起來就像被凍結(jié)在某個(gè)時(shí)間點(diǎn)上,不可以出現(xiàn)分析過程中對(duì)象引用關(guān)系還在不斷變化的情況,這是保證分析結(jié)果準(zhǔn)確性的基礎(chǔ)。這點(diǎn)是導(dǎo)致GC進(jìn)行時(shí)必須停頓所有Java執(zhí)行線程(Sun將這件事情稱為“Stop The World”)的其中一個(gè)重要原因,即使是在號(hào)稱(幾乎)不會(huì)發(fā)生停頓的CMS收集器中,枚舉根節(jié)點(diǎn)時(shí)也是必須要停頓的。

準(zhǔn)確式GC與OopMap

由于目前的主流Java虛擬機(jī)使用的都是準(zhǔn)確式GC(即使用準(zhǔn)確式內(nèi)存管理,虛擬機(jī)可用知道內(nèi)存中某個(gè)位置的數(shù)據(jù)具體是什么類型),所以當(dāng)執(zhí)行系統(tǒng)停頓下來后,并不需要一個(gè)不漏地檢查完所有執(zhí)行上下文和全局的引用位置,虛擬機(jī)應(yīng)當(dāng)是有辦法直接得知哪些地方存放著對(duì)象引用。在HotSpot的實(shí)現(xiàn)中,是使用一組稱為OopMap的數(shù)據(jù)結(jié)構(gòu)來達(dá)到這個(gè)目的的,在類加載完成的時(shí)候,HotSpot就把對(duì)象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)計(jì)算出來,在JIT編譯過程中,也會(huì)在特定的位置記錄下棧和寄存器中哪些位置是引用。這樣,GC在掃描時(shí)就可以直接得知這些信息了。

安全點(diǎn)(Safepoint)——進(jìn)行GC時(shí)程序停頓的位置

在OopMap的協(xié)助下,HotSpot可以快速且準(zhǔn)確地完成GC Roots枚舉,但一個(gè)很現(xiàn)實(shí)的問題隨之而來:可能導(dǎo)致引用關(guān)系變化,或者說OopMap內(nèi)容變化的指令非常多,如果為每一條指令都生成對(duì)應(yīng)的OopMap,那將會(huì)需要大量的額外空間,這樣GC的空間成本將會(huì)變得很高。

為此,HotSpot選擇不為每條指令都生成OopMap,而是只在“特定的位置”記錄這些信息,這些位置便被稱為安全點(diǎn)(Safepoint)。也就是說,程序執(zhí)行時(shí)并非在所有地方都能停頓下來開始GC,只有在到達(dá)安全點(diǎn)時(shí)才能暫停。Safepoint的選定既不能太少以致于讓GC等待時(shí)間太長,也不能過于頻繁以致于過分增大運(yùn)行時(shí)的負(fù)荷。所以,安全點(diǎn)的選定基本上是以程序“是否具有讓程序長時(shí)間執(zhí)行的特征”為標(biāo)準(zhǔn)進(jìn)行選定的——因?yàn)槊織l指令執(zhí)行的時(shí)間都非常短暫,程序不太可能因?yàn)橹噶盍鏖L度太長這個(gè)原因而過長時(shí)間運(yùn)行,“長時(shí)間執(zhí)行”的最明顯特征就是指令序列復(fù)用,例如方法調(diào)用、循環(huán)跳轉(zhuǎn)、異常跳轉(zhuǎn)等,所以具有這些功能的指令才會(huì)產(chǎn)生Safepoint。

對(duì)于Sefepoint,另一個(gè)需要考慮的問題是如何在GC發(fā)生時(shí)讓所有線程(這里不包括執(zhí)行JNI調(diào)用的線程)都“跑”到最近的安全點(diǎn)上再停頓下來。這里有兩種方案可供選擇:

  • 搶先式中斷(Preemptive Suspension)
    搶先式中斷不需要線程的執(zhí)行代碼主動(dòng)去配合,在GC發(fā)生時(shí),首先把所有線程全部中斷,如果發(fā)現(xiàn)有線程中斷的地方不在安全點(diǎn)上,就恢復(fù)線程,讓它“跑”到安全點(diǎn)上。現(xiàn)在幾乎沒有虛擬機(jī)實(shí)現(xiàn)采用搶先式中斷來暫停線程從而響應(yīng)GC事件。
  • 主動(dòng)式中斷(Voluntary Suspension)
    主動(dòng)式中斷的思想是當(dāng)GC需要中斷線程的時(shí)候,不直接對(duì)線程操作,僅僅簡單地設(shè)置一個(gè)標(biāo)志,各個(gè)線程執(zhí)行時(shí)主動(dòng)去輪詢這個(gè)標(biāo)志,發(fā)現(xiàn)中斷標(biāo)志為真時(shí)就自己中斷掛起。輪詢標(biāo)志的地方和安全點(diǎn)是重合的,另外再加上創(chuàng)建對(duì)象需要分配內(nèi)存的地方。

安全區(qū)域(Safe Region)

Safepoint機(jī)制保證了程序執(zhí)行時(shí),在不太長的時(shí)間內(nèi)就會(huì)遇到可進(jìn)入GC的Safepoint。但是,程序“不執(zhí)行”的時(shí)候(如線程處于Sleep狀態(tài)或Blocked狀態(tài)),這時(shí)線程無法響應(yīng)JVM的中斷請(qǐng)求,“走到”安全的地方去中斷掛起,這時(shí)候就需要安全區(qū)域(Safe Region)來解決。

安全區(qū)域是指在一段代碼片段之中,引用關(guān)系不會(huì)發(fā)生變化。在這個(gè)區(qū)域中的任意地方開始GC都是安全的。我們也可以把Safe Region看做是被擴(kuò)展了的Safepoint。

在線程執(zhí)行到Safe Region中的代碼時(shí),首先標(biāo)識(shí)自己已經(jīng)進(jìn)入了Safe Region,那樣,當(dāng)在這段時(shí)間里JVM要發(fā)起GC時(shí),就不用管標(biāo)識(shí)自己為Safe Region狀態(tài)的線程了。在線程要離開Safe Region時(shí),它要檢查系統(tǒng)是否已經(jīng)完成了根節(jié)點(diǎn)枚舉(或者是整個(gè)GC過程),如果完成了,那線程就繼續(xù)執(zhí)行,否則它就必須等待直到收到可以安全離開Safe Region的信號(hào)為止。

內(nèi)存分配策略

Java的自動(dòng)內(nèi)存管理最終可以歸結(jié)為自動(dòng)化地解決了兩個(gè)問題:

  • 給對(duì)象分配內(nèi)存
  • 回收分配給對(duì)象的內(nèi)存

對(duì)象的內(nèi)存分配通常是在堆上分配(除此以外還有可能經(jīng)過JIT編譯后被拆散為標(biāo)量類型并間接地棧上分配),對(duì)象主要分配在新生代的Eden區(qū)上,如果啟動(dòng)了本地線程分配緩沖,將按線程優(yōu)先在TLAB上分配。少數(shù)情況下也可能會(huì)直接分配在老年代中,分配的規(guī)則并不是固定的,實(shí)際取決于垃圾收集器的具體組合以及虛擬機(jī)中與內(nèi)存相關(guān)的參數(shù)的設(shè)置。至于內(nèi)存回收策略,在上文已經(jīng)描述得很詳盡了。

下面以使用Serial/Serial Old收集器(將在下一篇文章中講解)為例,介紹內(nèi)存分配的策略。

對(duì)象優(yōu)先在Eden區(qū)分配

大多數(shù)情況下,對(duì)象在新生代的Eden區(qū)中分配。當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時(shí),虛擬機(jī)將發(fā)起一次Minor GC。

大對(duì)象直接進(jìn)入老年代

所謂的大對(duì)象是指,需要大量連續(xù)內(nèi)存空間的Java對(duì)象,最典型的大對(duì)象就是很長的字符串以及數(shù)組。大對(duì)象對(duì)虛擬機(jī)的內(nèi)存分配來說是一個(gè)壞消息(尤其是遇到朝生夕滅的“短命大對(duì)象”,寫程序時(shí)應(yīng)避免),經(jīng)常出現(xiàn)大對(duì)象容易導(dǎo)致內(nèi)存還有不少空間時(shí)就提前觸發(fā)GC以獲取足夠的連續(xù)空間來安置它們

虛擬機(jī)提供了一個(gè)-XX:PretenureSizeThreshold參數(shù),令大于這個(gè)設(shè)置值的對(duì)象直接在老年代分配。這樣做的目的是避免在Eden區(qū)及兩個(gè)Survivor區(qū)之間發(fā)生大量的內(nèi)存復(fù)制(新生代采用復(fù)制算法回收內(nèi)存)。

長期存活的對(duì)象將進(jìn)入老年代

既然虛擬機(jī)采用了分代收集的思想來管理內(nèi)存,那么內(nèi)存回收時(shí)就必須能識(shí)別哪些對(duì)象應(yīng)放在新生代,哪些對(duì)象應(yīng)放在老年代中。為了做到這點(diǎn),虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器。如果對(duì)象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor容納的話,將被移動(dòng)到Survivor空間中,并且對(duì)象年齡設(shè)為1。對(duì)象在Survivor區(qū)中每“熬過”一次Minor GC,年齡就增加1歲,當(dāng)它的年齡增加到一定程度(默認(rèn)為15歲),就將會(huì)被晉升到老年代中。對(duì)象晉升老年代的年齡閾值,可以通過參數(shù)-XX:MaxTenuringThreshold設(shè)置。

動(dòng)態(tài)對(duì)象年齡判定

為了能更好地適應(yīng)不同程序的內(nèi)存狀況,虛擬機(jī)并不是永遠(yuǎn)地要求對(duì)象的年齡必須達(dá)到了MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代,無須等到MaxTenuringThreshold中要求的年齡。

空間分配擔(dān)保

在發(fā)生Minor GC之前,虛擬機(jī)會(huì)先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象總空間,如果這個(gè)條件成立,那么Minor GC可以確保是安全的。如果不成立,則虛擬機(jī)會(huì)查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗。如果允許,那么會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于,將嘗試著進(jìn)行一次Minor GC,盡管這次Minor GC是有風(fēng)險(xiǎn)的;如果小于,或者HandlePromotionFailure設(shè)置不允許冒險(xiǎn),那這時(shí)也要改為進(jìn)行一次Full GC

前面提到過,新生代使用復(fù)制收集算法,但為了內(nèi)存利用率,只使用其中一個(gè)Survivor空間來作為輪換備份,因此當(dāng)出現(xiàn)大量對(duì)象在Minor GC后仍然存活的情況(最極端的情況就是內(nèi)存回收后新生代中所有對(duì)象都存活),就需要老年代進(jìn)行分配擔(dān)保,把Survivor無法容納的對(duì)象直接進(jìn)入老年代。與生活中的貸款擔(dān)保類似,老年代要進(jìn)行這樣的擔(dān)保,前提是老年代本身還有容納這些對(duì)象的剩余空間,一共有多少對(duì)象會(huì)活下來在實(shí)際完成內(nèi)存回收之前是無法明確知道的,所以只好取之前每一次回收晉升到老年代對(duì)象容量的平均大小值作為經(jīng)驗(yàn)值,與老年代的剩余空間進(jìn)行比較,決定是否進(jìn)行Full GC來讓老年代騰出更多空間。

取平均值進(jìn)行比較其實(shí)仍然是一種動(dòng)態(tài)概率的手段,也就是說,如果某次Minor GC存活后的對(duì)象突增,遠(yuǎn)遠(yuǎn)高于平均值的話,依然會(huì)導(dǎo)致擔(dān)保失敗(Handle Promotion Failure)。如果出現(xiàn)了HandlePromotionFailure失敗,那就只好在失敗后重新發(fā)起一次Full GC。雖然擔(dān)保失敗時(shí)繞的圈子是最大的,但大部分情況下都還是會(huì)將HandlePromotionFailure開關(guān)打開,避免Full GC過于頻繁。

Full GC的觸發(fā)條件

對(duì)于Minor GC,其觸發(fā)條件非常簡單,當(dāng)Eden區(qū)空間滿時(shí),就將觸發(fā)一次Minor GC。而Full GC則相對(duì)復(fù)雜,因此本節(jié)我們主要介紹Full GC的觸發(fā)條件。

調(diào)用System.gc()

此方法的調(diào)用是建議JVM進(jìn)行Full GC,雖然只是建議而非一定,但很多情況下它會(huì)觸發(fā) Full GC,從而增加Full GC的頻率,也即增加了間歇性停頓的次數(shù)。因此強(qiáng)烈建議能不使用此方法就不要使用,讓虛擬機(jī)自己去管理它的內(nèi)存,可通過-XX:+ DisableExplicitGC來禁止RMI調(diào)用System.gc()。

老年代空間不足

老年代空間不足的常見場景為前文所講的大對(duì)象直接進(jìn)入老年代、長期存活的對(duì)象進(jìn)入老年代等,當(dāng)執(zhí)行Full GC后空間仍然不足,則拋出如下錯(cuò)誤:
Java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的Full GC,調(diào)優(yōu)時(shí)應(yīng)盡量做到讓對(duì)象在Minor GC階段被回收、讓對(duì)象在新生代多存活一段時(shí)間及不要?jiǎng)?chuàng)建過大的對(duì)象及數(shù)組。

空間分配擔(dān)保失敗

前文介紹過,使用復(fù)制算法的Minor GC需要老年代的內(nèi)存空間作擔(dān)保,如果出現(xiàn)了HandlePromotionFailure擔(dān)保失敗,則會(huì)觸發(fā)Full GC。

JDK 1.7及以前的永久代空間不足

在JDK 1.7及以前,HotSpot虛擬機(jī)中的方法區(qū)是用永久代實(shí)現(xiàn)的,永久代中存放的為一些class的信息、常量、靜態(tài)變量等數(shù)據(jù),當(dāng)系統(tǒng)中要加載的類、反射的類和調(diào)用的方法較多時(shí),Permanet Generation可能會(huì)被占滿,在未配置為采用CMS GC的情況下也會(huì)執(zhí)行Full GC。如果經(jīng)過Full GC仍然回收不了,那么JVM會(huì)拋出如下錯(cuò)誤信息:
java.lang.OutOfMemoryError: PermGen space
為避免PermGen占滿造成Full GC現(xiàn)象,可采用的方法為增大PermGen空間或轉(zhuǎn)為使用CMS GC。

在JDK 1.8中用元空間替換了永久代作為方法區(qū)的實(shí)現(xiàn),元空間是本地內(nèi)存,因此減少了一種Full GC觸發(fā)的可能性。

Concurrent Mode Failure

執(zhí)行CMS GC的過程中同時(shí)有對(duì)象要放入老年代,而此時(shí)老年代空間不足(有時(shí)候“空間不足”是CMS GC時(shí)當(dāng)前的浮動(dòng)垃圾過多導(dǎo)致暫時(shí)性的空間不足觸發(fā)Full GC),便會(huì)報(bào)Concurrent Mode Failure錯(cuò)誤,并觸發(fā)Full GC。

小結(jié)

本文簡要地介紹了HotSpot虛擬機(jī)如何去發(fā)起內(nèi)存回收的問題,也解答了文章開頭提出的三個(gè)問題中的前兩個(gè)——“哪些內(nèi)存需要回收”和“何時(shí)回收”,同時(shí)對(duì)于第三個(gè)問題——“如何回收”,在原理層面作出了解答。在下一篇文章中,筆者將通過介紹幾種具體的垃圾收集器,來更深入地回答第三個(gè)問題。

參考資料

  • 《深入理解Java虛擬機(jī)——JVM高級(jí)特性與最佳實(shí)踐》-周志明
  • CS-Note——Java:java虛擬機(jī)
  • JVM 垃圾回收器工作原理及使用實(shí)例介紹

?

原文:https://meandni.com/2019/01/11/jvm_note2/

總結(jié)

以上是生活随笔為你收集整理的《深入理解java虚拟机》笔记2——GC算法与内存分配策略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

亚洲一级性 | 日韩av进入 | 日韩免费播放 | 午夜12点 | 亚洲综合狠狠干 | 久久久精品国产一区二区 | 亚洲狠狠 | 91精品国产麻豆 | 国产午夜三级一二三区 | 国产亚洲免费的视频看 | 免费看久久久 | 91高清不卡 | 国产美女视频免费观看的网站 | 国产欧美综合在线观看 | 久久黄色影视 | 免费看日韩 | 久操视频在线观看 | 亚洲劲爆av | 日本性生活免费看 | 亚洲 欧美 日韩 综合 | 欧美另类网站 | 亚洲精品视频在线观看免费视频 | 91热这里只有精品 | 日本黄色免费大片 | 在线成人中文字幕 | 久久久久在线观看 | 国产精品男女啪啪 | 日韩精品一区二区不卡 | 久久躁日日躁aaaaxxxx | 日韩专区一区二区 | 久久这里 | 欧美日韩精品在线观看视频 | 中文字幕第一 | 国产精品久久久久久影院 | 久久免费视频4 | 精品久久久久久久久久久久久久久久 | 91精品国产自产在线观看永久 | 日韩美女一级片 | 超碰免费av | 91av蜜桃 | 99久久精品国产一区二区成人 | 日韩在线无 | 精品国产一区二 | 亚洲精品一区二区18漫画 | 国产一级大片免费看 | 欧美在线aaa | 中文字幕第一页在线播放 | 成人午夜在线观看 | 人人讲| 999成人国产 | 成人播放器 | 国产一二区免费视频 | 四虎免费在线观看视频 | 91最新视频在线观看 | 毛片一级免费一级 | 日韩二三区| 国产精品久久久久久久7电影 | 超碰在线1 | 午夜精品久久久久久久99无限制 | 波多野结衣电影一区 | 国产精品久久久久久久久婷婷 | 成人毛片一区 | 亚州人成在线播放 | 国产精品久久久久av福利动漫 | 欧美精选一区二区三区 | 国产精品久久久久久久久久久久午夜 | 综合色婷婷 | 一区二区三区日韩视频在线观看 | 最新国产精品久久精品 | 丁香六月婷婷开心婷婷网 | 人人舔人人干 | 欧美国产精品一区二区 | 亚洲国产天堂av | 日韩欧美精品在线 | 国产精品激情 | 日日狠狠 | 欧美色就是色 | 日韩aⅴ视频 | 六月丁香六月婷婷 | 爱爱av网 | 久久99精品热在线观看 | 亚洲综合视频网 | 免费在线黄色av | 国产一级片免费视频 | 综合久久五月天 | 精品美女视频 | 六月丁香六月婷婷 | 国色天香在线观看 | 成人免费在线播放 | 国产精品免费久久久久久 | 久草免费在线观看 | 中文在线字幕免费观看 | 国产精品久久久影视 | 日韩国产欧美在线播放 | 91成人破解版 | 欧美少妇影院 | 91麻豆网| 欧美做受xxx | 啪嗒啪嗒免费观看完整版 | 国产精品自产拍在线观看桃花 | 9797在线看片亚洲精品 | 97成人精品视频在线观看 | 国产一级免费视频 | 国产传媒中文字幕 | 六月丁香婷婷网 | 精品国产一区二区久久 | 天天插天天爱 | 四虎小视频 | 欧美先锋影音 | 99re国产视频 | 91视频在线免费 | 日韩性久久 | 国产高清小视频 | 青青久视频 | 久日精品 | 久草香蕉在线视频 | 一区二区 精品 | 久久免费播放视频 | 成人app在线播放 | 日日草夜夜操 | 久久久在线观看 | av在线进入 | 日本激情中文字幕 | 国产高清区 | 亚洲一区不卡视频 | 日韩av午夜在线观看 | 久久麻豆精品 | 狠狠干网| 亚洲精品玖玖玖av在线看 | 天天操天天操一操 | 日韩精品中文字幕在线不卡尤物 | 96视频在线 | 免费观看一区二区 | 国产盗摄精品一区二区 | 日韩黄在线观看 | 免费看黄色91 | 99精品免费观看 | 国产一级久久久 | 日韩av电影国产 | 日本三级久久久 | 日韩有码在线播放 | 亚洲精品视频免费在线 | 亚洲一二视频 | 三级大片网站 | 99精品视频在线观看免费 | 国产黄色高清 | 久久99国产综合精品免费 | 国产精品久久久影视 | 7799av| 欧美日韩一级在线 | 国产成人高清av | 国产69精品久久99的直播节目 | 国产成人一区二区精品非洲 | 国产香蕉久久精品综合网 | 国产欧美综合视频 | 欧美一区二区三区在线 | 国产精品一区二区在线播放 | 午夜性盈盈 | 亚洲国产成人精品久久 | 免费观看十分钟 | 欧美片一区二区三区 | 午夜国产在线观看 | 一级黄色免费网站 | 日本黄色免费在线观看 | 国产尤物视频在线 | 国产尤物视频在线 | 欧美大香线蕉线伊人久久 | av中文字幕在线看 | 久色网| 国产精品99久久免费黑人 | 精品一区二区三区在线播放 | 片网站 | 国产视频日韩视频欧美视频 | 成人动漫精品一区二区 | 在线免费观看国产视频 | 精品国偷自产国产一区 | 国产在线a免费观看 | 久久男人中文字幕资源站 | 麻豆视频在线观看免费 | 天天色棕合合合合合合 | 最近在线中文字幕 | 成人av在线直播 | 亚洲精品小区久久久久久 | 精品一区中文字幕 | 韩国一区在线 | 少妇视频在线播放 | 久久狠狠一本精品综合网 | 久久久五月天 | 国产精品美女在线观看 | 日韩欧美高清一区二区三区 | 色婷婷av在线 | 激情网站 | 久久黄色网页 | www.国产毛片 | 免费av网站观看 | www.777奇米 | 久久综合久久综合久久综合 | 免费黄色网止 | 在线激情影院一区 | 人人cao| 国产美女免费视频 | 四虎国产精品免费 | 日韩欧美一区二区不卡 | 国产精品免费久久久久久久久久中文 | 少妇bbbb揉bbbb日本 | 日日干天天爽 | 欧美色综合久久 | 五月婷网 | 激情综合电影网 | 91av视频导航 | 天堂av最新网址 | 久久精视频| 日韩欧美不卡 | 久久人操| 亚洲伊人婷婷 | 五月激情久久 | 777奇米四色| 亚洲黄色app| 亚洲黄色免费在线 | 麻豆成人在线观看 | 成人av片免费看 | 国内精品久久久久久久久久清纯 | 婷婷色六月天 | 操操操日日日干干干 | 91视频免费观看 | 91精品国产99久久久久 | 麻豆传媒视频在线播放 | 六月婷操| 色悠悠久久综合 | 97视频在线观看视频免费视频 | 丁香婷婷综合色啪 | 精品福利片| www.综合网.com| 日韩理论片在线观看 | 免费看一级黄色 | 国产黄色在线网站 | 91看片一区二区三区 | 狠狠撸电影 | 最近免费中文字幕大全高清10 | 伊人色综合久久天天网 | 国产在线免费av | 精品在线小视频 | 久久久国产精华液 | 久久免费在线观看 | 久久精品一区二区国产 | 最近中文字幕免费av | 亚洲精品美女久久 | 久久1电影院 | 日韩在线观看视频中文字幕 | 最近中文字幕国语免费高清6 | 欧美 亚洲 另类 激情 另类 | 久久伊人操 | 超碰公开97 | 免费看黄色毛片 | 成人av中文字幕在线观看 | www.五月天婷婷 | 日本护士撒尿xxxx18 | 精品久久亚洲 | 欧美精品二区 | 国产精品va在线观看入 | 国产一区二区三区四区在线 | 国产精品第10页 | 国产精品久久片 | 久久久精品电影 | 成人精品影视 | 久艹在线观看视频 | 精品久久精品 | 18久久久久 | 日本狠狠色 | 欧美日韩视频免费看 | 国产精品 日本 | 日韩 精品 一区 国产 麻豆 | 在线观看视频在线观看 | 精品a级片 | 香蕉久久久久久久 | 久久国产日韩 | 成人一级黄色片 | 欧美在线视频一区二区 | 欧美日韩国产二区三区 | 久草视频播放 | 伊人一级 | 亚洲 中文 在线 精品 | 在线观看视频在线观看 | 亚洲伦理电影在线 | 国产69精品久久久久久久久久 | 国产精品毛片网 | 黄a网| 最近中文字幕国语免费av | 国产精品一区二区久久久 | 久久6精品 | 久久婷婷色综合 | 在线视频成人 | 成人a在线| 一区二区三区国产欧美 | 日韩欧美在线综合网 | 国产精品电影一区 | 天天综合久久综合 | 国产亚洲成人网 | 色综合久久久久网 | 久草线| 久久久久网站 | 亚洲综合视频在线播放 | 久久国产精品99国产精 | 91成人精品 | av中文字幕不卡 | 国内精品免费久久影院 | 国产一区在线视频播放 | 国产福利一区二区在线 | 日本一区二区三区视频在线播放 | 欧美一区二区三区在线视频观看 | 中文字幕在线视频一区 | 免费黄色a级毛片 | 欧美另类视频 | 99久久日韩精品免费热麻豆美女 | 五月天婷婷狠狠 | 99精品欧美一区二区三区 | 欧美日韩另类视频 | 欧美日韩视频在线 | 天天做天天射 | 日韩精品久久中文字幕 | 欧美怡红院 | 性色av一区二区 | 91丨九色丨国产丨porny精品 | 国产高清网站 | 成人动漫视频在线 | 久久精品一二三区白丝高潮 | 国产黑丝一区二区三区 | 黄p在线播放 | 日韩啪视频 | 亚洲专区路线二 | 国产小视频你懂的在线 | 亚洲专区 国产精品 | www,黄视频| 日p视频在线观看 | 精品久久久久久国产91 | 色网站在线免费观看 | 久久久久一区二区三区 | 91九色视频在线播放 | 日韩在线观看小视频 | 欧美精品免费在线观看 | 亚洲 欧洲av | 免费精品视频在线 | 国产乱码精品一区二区蜜臀 | 国产在线传媒 | 五月激情五月激情 | 在线观看免费高清视频大全追剧 | 欧美极品xxx| 99综合久久 | 少妇bbw撒尿 | 国产一区免费在线观看 | 成人性生交大片免费观看网站 | 免费观看一区二区 | av在线等| 亚洲理论片在线观看 | 免费在线观看av | 欧美成人h版在线观看 | av一级黄| 96久久精品 | 亚洲一区二区三区毛片 | 久久精品久久久精品美女 | 毛片在线网 | 欧美伦理电影一区二区 | 国产高清综合 | 亚洲欧美视屏 | 最近的中文字幕大全免费版 | 高潮久久久 | 永久免费视频国产 | 亚洲一区二区高潮无套美女 | 日韩精品一区二区在线观看视频 | 丁香5月婷婷久久 | 国产99精品| 胖bbbb搡bbbb擦bbbb | 国产日韩中文字幕 | www.com久久| 黄色h在线观看 | 亚洲高清在线精品 | 成人小视频免费在线观看 | 伊人久在线 | 99久久激情 | 久久久久久久久久久久久国产精品 | 深爱五月激情五月 | 99久久精品国 | 三级黄色理论片 | 午夜在线日韩 | 99在线观看视频网站 | 亚洲国产日韩欧美 | 亚洲精品高清视频 | 欧美一级日韩免费不卡 | 97在线观看免费高清完整版在线观看 | 亚洲精品自拍视频在线观看 | 黄色av免费看 | 国产一级大片在线观看 | 中文字幕中文字幕在线中文字幕三区 | av在线免费不卡 | 97超碰人人干 | 久久久久久久久免费视频 | 一本到在线| 99久久久久久久久久 | 182午夜在线观看 | 国产一区二区三区免费观看视频 | 午夜精品久久久久久久久久久久久久 | 婷婷色在线资源 | 国产亚洲视频在线观看 | 久久国产精品久久国产精品 | 99久久精品费精品 | 色天堂在线视频 | 亚洲人片在线观看 | 久久精品国产免费 | 亚洲精品小视频在线观看 | av永久网址 | 天堂网av 在线 | 欧美激情视频在线观看免费 | 波多野结衣电影一区二区 | av片免费播放 | 天天摸天天弄 | 伊人开心激情 | 午夜视频免费播放 | 婷婷5月激情5月 | 色香蕉在线视频 | 久久精品精品电影网 | 亚洲美女在线一区 | 亚洲日本在线视频观看 | 日本激情动作片免费看 | 国产精品一区二区三区99 | 国产三级国产精品国产专区50 | 国产a视频免费观看 | 91成人在线网站 | 久久最新网址 | 丝袜美腿亚洲综合 | 国产精品久久久久久久免费观看 | 99欧美视频 | 久久午夜国产精品 | 伊人久久国产精品 | 国产999精品 | 一区二区三区在线免费观看 | 亚洲精品美女免费 | 亚州精品在线视频 | 日日干美女 | 国产自偷自拍 | 五月婷婷香蕉 | 欧美精品中文字幕亚洲专区 | 亚洲欧洲精品久久 | 91丨九色丨蝌蚪丰满 | 国产.精品.日韩.另类.中文.在线.播放 | 亚洲 欧洲 国产 日本 综合 | 国产粉嫩在线观看 | 狠狠操狠狠干天天操 | 在线观看中文字幕dvd播放 | 欧美日韩国产精品久久 | 久久久久综合网 | 色综合中文综合网 | 成人三级网址 | 美女黄色网在线播放 | 五月婷婷激情六月 | 国产精品久久9 | 国产精品免费久久久久久久久久中文 | 99色在线视频 | 日本精品视频在线播放 | 日韩有码网站 | 黄色三级免费 | free,性欧美 九九交易行官网 | 成人精品在线 | 99在线国产 | 黄污在线看 | 一区二区三区在线观看中文字幕 | 91在线视频免费91 | 久久这里只有精品视频首页 | 亚洲精品视频二区 | 免费在线观看成人 | 99这里只有精品99 | 国产精品三级视频 | 欧美日韩中文字幕在线视频 | 亚洲无吗av| 91精品久久久久久久久久入口 | 精品亚洲免费 | 国产精品久久久亚洲 | 国产精品久久久久久久久久ktv | 一级免费av | 手机成人av | 日韩欧美在线国产 | 日日精品 | 国产91免费在线观看 | 911久久 | 天天透天天插 | 奇米影视四色8888 | 久久国产午夜精品理论片最新版本 | 日韩精选在线观看 | 亚洲性xxxx | 久久久午夜视频 | 在线观看日本高清mv视频 | 婷婷在线不卡 | 91伊人| 日韩电影中文字幕在线 | 少妇性bbb搡bbb爽爽爽欧美 | 国产精品久久久久久久免费大片 | 色5月婷婷 | 国产免费观看久久 | 日本精品免费看 | 国产香蕉视频在线播放 | 中文在线免费视频 | 天天躁日日 | 免费毛片一区二区三区久久久 | 91麻豆免费视频 | a黄色大片| 亚洲天堂网站视频 | 全黄色一级片 | 国产亚洲精品久久19p | 搡bbbb搡bbb视频 | 免费在线观看黄网站 | 三级免费黄 | 亚洲国产网站 | 日产乱码一二三区别免费 | 久久久天堂 | 一区二区视频欧美 | 四虎影视国产精品免费久久 | 中文字幕在线日 | 深爱激情久久 | 国产精品12345 | 九九九热精品 | 91麻豆精品国产 | 久草在线高清 | 91久久久久久国产精品 | 日韩精品1区2区 | 国产精品va视频 | 免费三级影片 | 特级aaa毛片 | 亚洲一级片在线观看 | 五月婷婷网站 | 国产中文字幕网 | 夜夜躁狠狠躁日日躁视频黑人 | 天天操比 | 国产亚洲日 | 国产日韩在线播放 | 99精品视频在线播放观看 | 成 人 免费 黄 色 视频 | 国偷自产中文字幕亚洲手机在线 | 91av视频播放| 二区三区精品 | 国产精品免费观看国产网曝瓜 | 亚洲激情在线 | av无限看| 日韩高清三区 | 久操视频在线观看 | 国产在线久久久 | 四虎成人精品永久免费av | 日韩精品久久久久久久电影竹菊 | 久久国产精品视频 | 91九色在线| 欧美日韩国产二区 | 91av电影在线 | 狠狠干.com | 欧美地下肉体性派对 | 成人av电影在线 | 91九色蝌蚪 | 天天艹 | 久久久精品 | 国产福利91精品一区二区三区 | 国产精品午夜久久 | 91免费高清在线观看 | 国产成人久久精品77777 | 精品美女久久久久 | 精品久久91 | 午夜美女福利直播 | av福利在线看 | 五月婷婷六月丁香 | 国产污视频在线观看 | 91网在线观看| 一区二区三区四区免费视频 | 中文字幕在线免费观看视频 | 精品成人a区在线观看 | 狠狠色噜噜狠狠狠狠2021天天 | 国产视频中文字幕 | 国产福利av在线 | 午夜视频在线观看一区二区三区 | 国产在线999| 97av视频 | 99av在线视频| 黄色精品在线看 | 91成人黄色 | 99热超碰 | 丰满少妇麻豆av | 欧美一区二区三区特黄 | 美女福利视频 | 美女视频黄免费的久久 | 九月婷婷人人澡人人添人人爽 | 国产理伦在线 | 日韩欧美在线一区二区 | 成人久久18免费 | 国产日韩欧美在线影视 | 国产免费午夜 | 韩国av一区二区三区 | 国产精品久久av | 毛片网站在线看 | 免费视频国产 | 久久综合精品一区 | 国产亚洲综合性久久久影院 | 欧美精品黑人性xxxx | 精品视频免费看 | 天天艹日日干 | 激情中文在线 | 久久久久久久久久久免费视频 | 国产精品久久一区二区三区, | 久久免费99精品久久久久久 | 久久视精品| 极品久久久久久久 | 午夜精品久久久久久久久久久久久久 | 精品久久国产精品 | 香蕉视频久久 | 久久这里只有精品首页 | 久久精品久久久久 | 中文字幕在线一区二区三区 | 91视频a| 欧美最爽乱淫视频播放 | 欧美性色黄大片在线观看 | 91精品专区 | 国产精品99免视看9 国产精品毛片一区视频 | 婷婷丁香花 | 精品字幕在线 | 天天操天天摸天天爽 | 国产99久久久国产精品成人免费 | 久久艹艹| 在线观看亚洲a | 美女久久视频 | 国产精品白丝jk白祙 | 狠狠躁夜夜躁人人爽视频 | 天天做日日做天天爽视频免费 | www.久久免费视频 | 色综合网 | 亚洲电影av在线 | 精品在线一区二区 | 欧美日韩国产综合一区二区 | 色 免费观看 | 在线免费观看黄网站 | 一级黄色免费 | 国内三级在线观看 | 国产一区二区电影在线观看 | 亚洲午夜精品在线观看 | 亚洲成av人片一区二区梦乃 | 欧美精品一区二区免费 | 99视频导航 | 精品欧美一区二区三区久久久 | 国产精品免费视频网站 | 国产精品久久久久久一区二区三区 | 国产馆在线播放 | 一级大片在线观看 | 国产成人av免费在线观看 | 精品欧美一区二区三区久久久 | 九色在线视频 | 国产九色视频在线观看 | 久久96国产精品久久99漫画 | 久久久国产精品人人片99精片欧美一 | 日韩精品视频免费 | 人人爽人人爽人人片av免 | 亚洲欧美日韩中文在线 | 亚洲开心色 | 欧美激情精品久久久久久免费印度 | 精品久久精品久久 | 五月婷婷色| 日韩v在线| 天天看天天干 | 久久夜色精品国产欧美乱极品 | 99久久激情视频 | 亚洲天堂网在线观看视频 | 韩国av免费看 | www.看片网站 | 免费观看xxxx9999片 | 国产婷婷精品av在线 | 91桃花视频 | 天天狠狠干 | 99这里只有精品视频 | 波多野结衣电影一区 | 国产精品视频永久免费播放 | 99热在线免费观看 | 色网站免费在线观看 | 久草视频中文在线 | 欧美日韩亚洲一 | 粉嫩aⅴ一区二区三区 | 国产美女视频一区 | 久久久久免费精品国产小说色大师 | 亚洲91网站 | 香蕉影视在线观看 | 在线观看完整版免费 | 成年性视频 | 免费观看的黄色片 | 国产夫妻av在线 | 青草草在线视频 | 久久国产手机看片 | 天天射天天射天天 | 精品久久久久久亚洲 | 粉嫩高清一区二区三区 | 97在线免费观看视频 | 精品福利在线视频 | 国产精品欧美日韩在线观看 | 91麻豆精品国产自产 | 中文区中文字幕免费看 | 99视频导航 | 91在线你懂的 | 欧美色精品天天在线观看视频 | 黄色精品久久久 | aⅴ视频在线 | 久草在线视频中文 | 黄色网中文字幕 | 久99精品 | 国模一区二区三区四区 | 国产小视频在线看 | 成人中文字幕+乱码+中文字幕 | 亚洲激情六月 | 欧美一级黄色视屏 | 在线免费观看视频一区 | 在线观看视频精品 | 日韩欧美在线观看 | 久久精品网址 | 美女视频是黄的免费观看 | 狠狠操导航 | 精品免费视频 | 欧美激情视频三区 | 国产成人免费网站 | 色狠狠干 | 亚洲精品乱码白浆高清久久久久久 | 久久精品视频2 | 国产精品亚洲精品 | 99热这里是精品 | 99视频导航 | 五月婷婷中文网 | 国产最新在线视频 | 国产精品电影一区二区 | 日韩二区三区在线观看 | 在线国产激情视频 | 日韩最新理论电影 | 婷婷五天天在线视频 | 国产小视频国产精品 | 又大又硬又黄又爽视频在线观看 | 精品视频久久久久久 | 欧美日韩免费一区二区 | 91亚州| 麻豆免费在线播放 | 又黄又爽又刺激的视频 | 成年人视频在线免费播放 | 亚洲欧美视频网站 | 国产精品福利av | 成人午夜网 | 亚洲精品高清一区二区三区四区 | 天天综合久久 | 亚洲另类xxxx | 精品久久久国产 | 国产精品久久久久久久久久 | 黄色影院在线观看 | 欧美日韩国产网站 | 2019av在线视频 | 欧美日韩高清一区二区 国产亚洲免费看 | 国产精品久久一卡二卡 | 六月婷色 | 91成人免费观看视频 | 国产手机在线观看视频 | 91片黄在线观看 | 欧美日韩一二三四区 | 精品在线观看国产 | 日韩精品中文字幕av | 久久成人黄色 | 精品国产免费av | 日本中文乱码卡一卡二新区 | 国产精品久久电影网 | 亚洲精品videossex少妇 | 欧美怡红院视频 | 91.麻豆视频 | 国产精品久久久区三区天天噜 | www.看片网站 | 国产成人精品一区二区在线 | 久久精品日产第一区二区三区乱码 | 国产专区在线视频 | 五月天av在线 | 国产97av | 日韩av网页 | 美女性爽视频国产免费app | 国产精品一区二区三区在线播放 | 欧美日一级片 | 91精彩在线视频 | 日本中文字幕在线观看 | 99视频久久 | 91在线永久 | 天天干天天干天天 | 九九视频网| 99r精品视频在线观看 | 免费av网站在线 | 国产精品一区二区三区久久 | 香蕉免费在线 | 91亚洲在线| 91精品久久久久久久99蜜桃 | 人九九精品 | 伊人射 | 国产一级精品在线观看 | 国产黄色免费 | 五月天婷婷在线观看视频 | av片在线观看 | 精品国产欧美一区二区三区不卡 | 久久成人亚洲欧美电影 | 在线视频一区观看 | 欧美成人aa | 久久久国产在线视频 | 亚洲精品一区二区三区高潮 | 中文字幕 成人 | 97在线观看免费高清完整版在线观看 | 国产精品1区2区3区在线观看 | 五月婷婷丁香网 | 超碰av在线 | 免费色视频 | 欧美精品久久久久久久久老牛影院 | 国产成人三级在线观看 | 国产破处在线视频 | 免费黄色av | 人人插人人插 | 激情久久伊人 | 最新色站 | 91成品人影院 | 激情久久久久 | 在线观看va | 在线亚洲日本 | 日韩欧美国产精品 | 精品国产电影一区 | 久久亚洲视频 | 天天色天天 | 在线一级片| 黄色在线观看免费 | 九九九毛片 | 久久精品999| av大片免费看| 99久久久国产精品免费99 | 中文字幕免费观看视频 | 亚洲综合小说 | 日本中出在线观看 | 亚洲国产精品久久久 | 五月婷丁香 | 在线观看国产福利片 | 最近中文字幕大全中文字幕免费 | 精品国产乱码久久久久久三级人 | 欧美一级性生活视频 | 精品电影一区 | 九九久| 久久久久北条麻妃免费看 | 干干干操操操 | 国产午夜三级一区二区三桃花影视 | 欧美日韩a视频 | 天堂av免费| 国产黄色精品在线 | 色播五月激情综合网 | 精品一区av | 黄色视屏在线免费观看 | 久久婷婷亚洲 | 精品一区中文字幕 | 亚洲精品国偷拍自产在线观看 | 黄色一级大片免费看 | 午夜视频在线观看网站 | 日韩成人黄色 | 天天色婷婷 | 免费观看成年人视频 | 欧美伦理一区二区 | 久久久免费精品 | 精产嫩模国品一二三区 | 久久精品免费播放 | 国产免费一区二区三区最新6 | 久草在线视频网站 | 伊人影院得得 | 色播激情五月 | 999电影免费在线观看 | 天天干.com | 中文在线最新版天堂 | 久久精品第一页 | 国产成人av一区二区三区在线观看 | 久久久污| 97超碰人人爱 | 久久精品久久99精品久久 | 久久99热这里只有精品 | 五月激情五月激情 | 五月婷婷综合久久 | 国产一卡在线 | 超碰在线观看99 | 天天色婷婷 | 久草久草久草久草 | 精品久久久久久久久久久久 | 51精品国自产在线 | 日韩精品久久中文字幕 | 欧美精品乱码久久久久久按摩 | 99久久网站 | 国产区精品在线观看 | 国产精品不卡在线观看 | 免费黄色激情视频 | 丁香久久 | 国产最新精品视频 | 国产精品www | 97碰在线视频 | 五月亚洲 | 成人啊 v| 亚洲精品一区二区三区高潮 | 久热精品国产 | 天天综合在线观看 | 一区二区三区四区五区六区 | 97在线免费视频观看 | 最近中文字幕免费av | 日日夜夜免费精品 | 免费影视大全推荐 | 激情五月视频 | 久久免费观看少妇a级毛片 久久久久成人免费 | 日批视频国产 | 最近久乱中文字幕 | 网址你懂的在线观看 | 热久久免费国产视频 | 国产精品不卡在线播放 | 黄网站色欧美视频 | 午夜视频不卡 | 久久99精品久久久久久秒播蜜臀 | 91精品老司机久久一区啪 | 亚洲国产精久久久久久久 | 日韩中文字幕视频在线 | 日日夜夜精品网站 | 午夜av在线 | 亚洲波多野结衣 | 777久久久 | 一区二区三区四区在线 | 99久久久久久国产精品 | 又黄又爽的免费高潮视频 | 精品久久网站 | 亚洲精品国产区 | 97电影网站| 97在线观看视频免费 | 91porny九色91啦中文 | 亚洲国产久 | 91污在线 | 99久久精品免费视频 | 激情综合五月天 | 欧美日韩国产一区二区在线观看 | 成人免费av电影 | 亚洲午夜精品一区二区三区电影院 | 天天搞夜夜骑 | 99久久精品免费看国产四区 | 园产精品久久久久久久7电影 | 一二区精品 | 亚州人成在线播放 | 在线观看国产91 | 成人精品在线 | 久热av| 国产精品综合久久久久 | 91看片淫黄大片在线播放 | 精品一区二区日韩 | 免费视频成人 | 91天天操| 国产一区二区三区久久久 | 99这里只有久久精品视频 | 国产99黄| 青青河边草免费视频 | 九色视频自拍 | 国产精品久久久久久超碰 | 国产成人久久77777精品 | 国产视频观看 | 中文字幕在线看视频 | 久久久久久久福利 | 欧美日韩国产精品一区二区 | 国产精品 中文字幕 亚洲 欧美 | 91国内在线 | 最近日本mv字幕免费观看 | 国产综合小视频 | 日韩欧美精品一区二区三区经典 | 国产精品在线看 | 午夜久久久精品 | 国产糖心vlog在线观看 | 成人羞羞视频在线观看免费 | 91丨九色丨蝌蚪丨老版 | 一级大片在线观看 | 色综合亚洲精品激情狠狠 | 免费看精品久久片 | 精品一区二区久久久久久久网站 | 国产一线二线三线性视频 | 国产不卡精品 | 综合网成人 | 天天操夜夜叫 | 国产精品福利av | 亚洲不卡av一区二区三区 | 日本最新一区二区三区 | 一区二区三区韩国免费中文网站 | 国产99久久久久 | 中文字幕二区 | 国产精久久久久久妇女av | 毛片在线网 | 国产精品一区二区免费视频 | 国产精品久久久久久影院 | 久久美女免费视频 | 亚洲欧美日韩不卡 | 欧美久久久久久 | 久久超级碰视频 | 国内精品久久久久国产 | 偷拍精偷拍精品欧洲亚洲网站 | 五月婷婷久草 | 最近中文字幕免费大全 | 免费久久99精品国产婷婷六月 | 97成人精品区在线播放 | 在线成人观看 | 一区二区三区四区五区六区 | 99精品欧美一区二区三区黑人哦 | 久久久久久久久久久久久国产精品 |