JVM 垃圾回收

注意 : 本系列文章為學(xué)習(xí)系列,部分內(nèi)容會(huì)取自相關(guān)書籍或者網(wǎng)絡(luò)資源,在文章中間和末尾處會(huì)有標(biāo)注

垃圾回收的意義

它使得java程序員不再時(shí)時(shí)刻刻的關(guān)注內(nèi)存管理方面的工作.

垃圾回收機(jī)制會(huì)自動(dòng)的管理jvm內(nèi)存空間,將那些已經(jīng)不會(huì)被使用到了的"垃圾對(duì)象"清理掉",釋放出更多的空間給其他對(duì)象使用.

何為對(duì)象的引用?

Java中的垃圾回收一般是在Java堆中進(jìn)行授艰,因?yàn)槎阎袔缀醮娣帕薐ava中所有的對(duì)象實(shí)例

在java中,對(duì)引用的概念簡(jiǎn)述如下(引用強(qiáng)度依次減弱) :

強(qiáng)引用: 這類引用是Java程序中最普遍的,只要強(qiáng)引用還存在米丘,垃圾收集器就永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象

軟引用: 用來描述一些非必須的對(duì)象,在系統(tǒng)內(nèi)存不夠使用時(shí),這類對(duì)象會(huì)被垃圾收集器回收,JDK提供了SoftReference類來實(shí)現(xiàn)軟引用

弱引用: 用來描述一些非必須的對(duì)象,只要發(fā)生GC,無論但是內(nèi)存是否夠用,這類對(duì)象就會(huì)被垃圾收集器回收,JDK提供了WeakReference類來實(shí)現(xiàn)弱引用

虛引用: 與其他幾種引用不同,它不影響對(duì)象的生命周期,如果這個(gè)對(duì)象是虛運(yùn)用,則就跟沒有引用一樣,在任何時(shí)刻都可能會(huì)回收,JDK提供了PhantomReference類來實(shí)現(xiàn)虛引用

如下為相關(guān)示例代碼

public class ReferenceDemo{

? publicstaticvoidmain(String[] args){

? ? ? //強(qiáng)引用

? ? ? Objectobject=newObject();

? ? ? Object[] objects =newObject[100];

? ? ?//軟引用

? ? ? SoftReference stringSoftReference =newSoftReference<>(newString("SoftReference"));

? ? ? System.out.println(stringSoftReference.get());

? ? ? System.gc();

? ? ? System.out.println(stringSoftReference.get());//手動(dòng)GC,這時(shí)內(nèi)存充足,對(duì)象沒有被回收

? ? //弱引用

? ? ?WeakReference stringWeakReference =newWeakReference<>(newString("WeakReference"));

? ? ?System.out.println(stringWeakReference.get());?

? ? ?System.gc();

? ? ?System.out.println(stringWeakReference.get());//手動(dòng)gc,這時(shí),返回null,對(duì)象已經(jīng)被回收System.out.println();

? ? //虛引用

//虛引用主要用來跟蹤對(duì)象被垃圾回收器回收的活動(dòng)滚粟。//虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用秽之。//當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)婶恼,如果發(fā)現(xiàn)它還有虛引用衰齐,就會(huì)在回收對(duì)象的內(nèi)存之前褒翰,把這個(gè)虛引用加入到與之 關(guān)聯(lián)的引用隊(duì)列中

? ? ? ReferenceQueue stringReferenceQueue =newReferenceQueue<>();

? ? ? ?PhantomReference stringPhantomReference =newPhantomReference<>(newString("PhantomReference"), stringReferenceQueue);

? ? ? ?System.out.println(stringPhantomReference.get());? ?

? }

}

當(dāng)然,關(guān)于這幾種引用還有很多知識(shí)點(diǎn),本文只做簡(jiǎn)單的介紹,后續(xù)有機(jī)會(huì)再單獨(dú)的文章詳細(xì)介紹.

如何確定需要回收的垃圾對(duì)象?

引用計(jì)數(shù)器

每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)器 , 新增一個(gè)引用的時(shí)候就+1,引用釋放的時(shí)候就-1,當(dāng)計(jì)數(shù)器為0的時(shí)候,就表示可以回收

引用計(jì)數(shù)算法的實(shí)現(xiàn)簡(jiǎn)單盈包,判定效率也很高,在大部分情況下它都是一個(gè)不錯(cuò)的選擇旬牲,當(dāng)Java語言并沒有選擇這種算法來進(jìn)行垃圾回收从祝,主要原因是它很難解決對(duì)象之間的相互循環(huán)引用問題

publicclassLoopReferenceDemo{publicstaticvoidmain(String[] args){? ? ? ? TestA a =newTestA();//1TestB b =newTestB();//2a.b = b;//3b.a = a;//4a =null;//5b =null;//6}? ? }classTestA{publicTestB b;}classTestB{publicTestA a;}

雖然a和b都為null,但是a和b存在循環(huán)引用,這樣a和b就永遠(yuǎn)不會(huì)被回收

如果你在互聯(lián)網(wǎng)上搜索"引用計(jì)數(shù)器"這個(gè)關(guān)鍵字,通常都會(huì)得到以上這一個(gè)結(jié)論,但是究竟為什么a和b不會(huì)被回,收其實(shí)還是沒有說清楚的,下面簡(jiǎn)單說明一下 :

第一行: TestA的引用計(jì)數(shù)器加1,TestA的引用數(shù)量為1

第二行: TestB的引用計(jì)數(shù)器加1,TestB的引用數(shù)量為1

第三行: TestB的引用計(jì)數(shù)器加1,TestB的引用數(shù)量為2

第四行: TestA的引用計(jì)數(shù)器加1,TestA的引用數(shù)量為2

內(nèi)存分布如下圖

第五行: 將a變量設(shè)置為null,不再指向堆中的引用,所以TestA的引用計(jì)數(shù)器減1,TestA的引用數(shù)量為1

第六行: 將b變量設(shè)置為null,不再指向堆中的引用,所以TestB的引用計(jì)數(shù)器減1,TestB的引用數(shù)量為1

內(nèi)存分布如下圖

結(jié)論: 雖然上面程序?qū)和b設(shè)置為null了,但是在堆中,TestA和TestB還是互相持有對(duì)方的引用,引用計(jì)數(shù)器依然不等于0,這個(gè)就稱為循環(huán)引用,所以說"引用計(jì)數(shù)器"會(huì)存在這個(gè)問題,導(dǎo)致這類對(duì)象無法被清理掉.

以上的知識(shí)點(diǎn)參考 :https://www.zhihu.com/question/21539353

可達(dá)性分析

雖然以上的"引用計(jì)數(shù)器"算法存在"循環(huán)引用"的問題,不過目前主流的虛擬機(jī)都采用"可達(dá)性分析(GC Roots Tracing)"算法來標(biāo)記那些對(duì)象是可以被回收的.

該算法是從GC Roots開始向下搜索,搜索走過的路徑稱之為引用鏈.當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連時(shí),就代表這個(gè)對(duì)象是不可用的.稱為"不可達(dá)對(duì)象"

GC Roots包括:

虛擬機(jī)棧(棧幀中的本地變量表)中的引用對(duì)象

方法區(qū)中的靜態(tài)屬性實(shí)體引用的對(duì)象

方法區(qū)中常量引用的對(duì)象

本地方法棧中JNI(Native方法)引用的對(duì)象

實(shí)際上,在根搜索算法中引谜,要真正宣告一個(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過程 :

如果對(duì)象在進(jìn)行根搜索后發(fā)現(xiàn)沒有與GC Roots相連接的引用鏈擎浴,那它會(huì)被第一次標(biāo)記并且進(jìn)行一次篩選员咽,篩選的條件是此對(duì)象是否有必要執(zhí)行finalize()方法

當(dāng)對(duì)象沒有覆蓋finalize()方法,或finalize()方法已經(jīng)被虛擬機(jī)調(diào)用過贮预,虛擬機(jī)將這兩種情況都視為沒有必要執(zhí)行

如果該對(duì)象被判定為有必要執(zhí)行finalize()方法贝室,那么這個(gè)對(duì)象將會(huì)被放置在一個(gè)名為F-Queue隊(duì)列中,并在稍后由一條由虛擬機(jī)自動(dòng)建立的仿吞、低優(yōu)先級(jí)的Finalizer線程去執(zhí)行finalize()方法

finalize()方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì)(因?yàn)橐粋€(gè)對(duì)象的finalize()方法最多只會(huì)被系統(tǒng)自動(dòng)調(diào)用一次), 稍后GC將對(duì)F-Queue中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記滑频,如果要在finalize()方法中成功拯救自己,只要在finalize()方法中讓該對(duì)象重引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián)即可

而如果對(duì)象這時(shí)還沒有關(guān)聯(lián)到任何鏈上的引用唤冈,那它就會(huì)被回收掉

如下圖所示

從上圖上看,reference1,2,3都是gc roots

reference1指向instance1,reference2指向instance4,并且instance4又指向了instance6,reference3則指向了instance2

所以說instance1,2,4,6都具有g(shù)c roots可達(dá)性,是存活著的對(duì)象,不會(huì)被垃圾回收器回收掉

而instance3,5則不具備gc roots可達(dá)性,是不可用對(duì)象,將會(huì)被垃圾回收器回收掉

從上圖描述"引用計(jì)數(shù)器"的圖例場(chǎng)景來看,TestA和TestB雖然互相有持有引用,但是并不具備gc roots可達(dá)性,所以,在"可達(dá)性分析"算法下,是會(huì)被垃圾回收器回收掉的

垃圾收集的算法

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

算法分為"標(biāo)記"和"清除"兩個(gè)階段,首先標(biāo)記出需要回收的對(duì)象,在標(biāo)記完成后,統(tǒng)一回收掉之前被標(biāo)記的所有對(duì)象. 它是最基礎(chǔ)的收集算法 . 后續(xù)的收集算法都是基于這種思想,并且對(duì)其缺點(diǎn)進(jìn)行改進(jìn)而產(chǎn)生的

主要缺點(diǎn):

效率問題 : 需要標(biāo)記和清除兩次掃描

空間問題 : 標(biāo)記和清除之后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存碎片,可能會(huì)導(dǎo)致,當(dāng)程序需要分配一個(gè)較大內(nèi)存空間的時(shí)候,無法找到足夠的連續(xù)內(nèi)存,從而不得不提前出發(fā)另外一次垃圾回收動(dòng)作

復(fù)制 算法

將可用內(nèi)存按容量劃分為兩塊,每次只使用其中的一塊,當(dāng)內(nèi)存使用完了后,就將還存活著的對(duì)象復(fù)制到另外一塊上面,然后在把前面一塊內(nèi)存一次性清理掉

優(yōu)點(diǎn) :

每次只操作一塊內(nèi)存,分配內(nèi)存的時(shí)候無需考慮內(nèi)存碎片的情況,只需要移動(dòng)對(duì)象的指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效

缺點(diǎn) :

會(huì)將內(nèi)存縮小為原來的一半

持續(xù)復(fù)制長(zhǎng)生期的對(duì)象則導(dǎo)致效率降低 (沒理解) (對(duì)于存活率較高的對(duì)象,就會(huì)對(duì)其進(jìn)行多次復(fù)制,從而導(dǎo)致效率降低)

標(biāo)記-壓縮 算法

和標(biāo)記-清除算法一樣,只不過標(biāo)記后的動(dòng)作不是清除,而是將所有對(duì)象向一端移動(dòng),然后直接清理掉邊界以外的對(duì)象(被標(biāo)記的對(duì)象)

特點(diǎn) :

復(fù)制算法比較適合于新生代峡迷,在老年代中,對(duì)象存活率比較高你虹,如果執(zhí)行較多的復(fù)制操作绘搞,效率將會(huì)變低,所以老年代一般會(huì)選用其他算法竟坛,如標(biāo)記—清理算法

該算法標(biāo)記的過程與標(biāo)記—清除算法中的標(biāo)記過程一樣永丝,但對(duì)標(biāo)記后出的垃圾對(duì)象的處理情況有所不同十嘿,它不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有的對(duì)象都向一端移動(dòng)蒿褂,然后直接清理掉端邊界以外的內(nèi)存

分代收集 算法

把java的堆分為"新生代"和"老年代",對(duì)于不同的年代采用不同算法

在新生代中,由于對(duì)象生命周期非常短暫,所以每次垃圾回收的時(shí)候都會(huì)有大量的對(duì)象死去,只有少量存活,這樣,采用"復(fù)制算法",就只需要付出少量存活對(duì)象的復(fù)制成本,就能完成回收

在老年代中,由于對(duì)象生命周期比較長(zhǎng),存活率較高,沒有額外的空間對(duì)它進(jìn)行分配和擔(dān)保,那就必須使用"標(biāo)記-清除算法"或者"標(biāo)記-壓縮算法"來進(jìn)行回收

Minor GC:從年輕代空間(包括Eden和Survivor區(qū)域)回收內(nèi)存被稱為Minor GC

Major GC:清理老年代

Full GC:清理整個(gè)堆空間—包括年輕代和老年代

年輕代:是所有新對(duì)象產(chǎn)生的地方.年輕代被分為3個(gè)部分(Enden區(qū)和兩個(gè)Survivor區(qū),也叫From和To),當(dāng)Eden區(qū)被對(duì)象填滿時(shí),就會(huì)執(zhí)行Minor GC,并把所有存活下來的對(duì)象轉(zhuǎn)移到其中一個(gè)survivor區(qū)(Form),Minor GC同樣會(huì)檢查存活下來的對(duì)象,并把它們轉(zhuǎn)移到另一個(gè)survivor區(qū)(To),這樣在一段時(shí)間內(nèi),總會(huì)有一個(gè)空的survivor區(qū),經(jīng)過多次GC周期后圆米,仍然存活下來的對(duì)象會(huì)被轉(zhuǎn)移到年老代內(nèi)存空間,常這是在年輕代有資格提升到年老代前通過設(shè)定年齡閾值來完成的,需要注意,Survivor的兩個(gè)區(qū)是對(duì)稱的,沒先后關(guān)系,from和to是相對(duì)的.

老年代:在年輕代中經(jīng)歷了N次回收后仍然沒有被清除的對(duì)象,就會(huì)被放到年老代中,都是生命周期較長(zhǎng)的對(duì)象.對(duì)于年老代,則會(huì)執(zhí)行Major GC,來清理.在某些情況下,則會(huì)觸發(fā)Full GC,來清理整個(gè)堆內(nèi)存

元空間:堆外的一部分內(nèi)存,通常直接使用的是系統(tǒng)內(nèi)存,用于存放運(yùn)行時(shí)常量池,等內(nèi)容,垃圾回收對(duì)應(yīng)元空間來說沒有明顯的影響

垃圾收集器

垃圾收集器是內(nèi)存回收算法的具體實(shí)現(xiàn)啄栓,Java虛擬機(jī)規(guī)范中對(duì)垃圾收集器應(yīng)該如何實(shí)現(xiàn)并沒有任何規(guī)定娄帖,因此不同廠商、不同版本的虛擬機(jī)所提供的垃圾收集器都可能會(huì)有很大的差別

Sun HotSpot虛擬機(jī)1.6版包含了如下收集器:Serial谴供、ParNew块茁、Parallel Scavenge、CMS桂肌、Serial Old数焊、Parallel Old

這些收集器以不同的組合形式配合工作來完成不同分代區(qū)的垃圾收集工作,如下是垃圾收集器簡(jiǎn)單介紹 :

Serial收集器

串行收集器,最古老,最穩(wěn)定,以及效率高的收集器,但是可能會(huì)造成程序較長(zhǎng)時(shí)間的停頓,只使用一個(gè)線程去回收.新生代,老年代使用串行回收

新生代使用"復(fù)制算法"

老年代使用"標(biāo)記壓縮算法"

垃圾回收的過程中會(huì)"程序暫停"(Stop the world)

ParNew收集器

是Serial收集器的多線程版,新生代并行,老年代串行

新生代使用"復(fù)制算法"

老年代使用"標(biāo)記壓縮算法"

垃圾回收的過程中會(huì)"程序暫停"(Stop the world)

Paralle收集器

類似于ParNew收集器,但是更關(guān)注系統(tǒng)的吞吐量.

可以通過參數(shù)來打開"自適應(yīng)調(diào)節(jié)策略",虛擬機(jī)會(huì)根據(jù)系統(tǒng)當(dāng)前的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整這些參數(shù)以便提供最合適的停頓時(shí)間和最大的吞吐量

也可以通過參數(shù)控制GC的時(shí)間不大于多少毫秒或者比例

新生代使用"復(fù)制算法"

老年代使用"標(biāo)記壓縮算法"

Parallel Old收集器

是Paralle收集器的老年代版本 , 使用多線程和"標(biāo)記-整理算法",這個(gè)收集器在JDK1.6中才開始使用

CMS收集器

是基于"標(biāo)記-清除"算法實(shí)現(xiàn)的,它的運(yùn)作過程相對(duì)于前面的其中收集器要復(fù)雜一些,整個(gè)過程分為4個(gè)步驟,包括 :

初始標(biāo)記(CMS initial mark)

并發(fā)標(biāo)記(CMS concurrent mark)

重新標(biāo)記(CMS remark)

并發(fā)清除(CMS concurrent sweep)

初始標(biāo)記和并發(fā)標(biāo)記仍需要Stop the World.

初始標(biāo)記僅僅只是標(biāo)記一下GC Root能直接關(guān)聯(lián)到的對(duì)象,速度很快.

并發(fā)標(biāo)記階段就是進(jìn)行GC Root Tracing的過程.

重新標(biāo)記這是為了修正并發(fā)標(biāo)記期間,因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記變動(dòng)的那一部分的標(biāo)記記錄,這一階段的停頓時(shí)間會(huì)比初始標(biāo)記階段的時(shí)間稍長(zhǎng)一些,但遠(yuǎn)比并發(fā)標(biāo)記時(shí)間短

整個(gè)過程中耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除過程中,收集器線程可以與用戶線程一起工作,所以總體來說,CMS收集器的內(nèi)存回收是與用戶線程一起并發(fā)執(zhí)行的

優(yōu)點(diǎn) : 并發(fā)收集,低停頓

缺點(diǎn) : 產(chǎn)生大量的空間碎片,并發(fā)階段會(huì)降低吞吐量

G1收集器

與CMS收集器項(xiàng)目,G1收集器有以下特點(diǎn) :

空間整合 :

G1收集器采用標(biāo)記-整理算法,不會(huì)產(chǎn)生空間碎片.分配大對(duì)象時(shí)不會(huì)應(yīng)為找不到連續(xù)的空間而提前觸發(fā)下一次GC

可預(yù)測(cè)停頓 :

降低停頓時(shí)間是G1和CMS的共同關(guān)注點(diǎn)

G1除了追求低停頓外,還能建立可預(yù)測(cè)的停頓時(shí)間模型.

能讓使用者明確指定在一個(gè)長(zhǎng)度為N毫秒的時(shí)間片段內(nèi),消耗在垃圾收集上的時(shí)間不得超過N毫秒,幾乎已經(jīng)是實(shí)時(shí)java(RTSJ)垃圾回收的特征了

上面提到的垃圾收集器,收集的范圍都是整個(gè)新生代或者老年代,而G1不在是這樣.

使用G1收集器的時(shí)候,JAVA堆的內(nèi)存布局與其他的收集器有很大的差別,它將這個(gè)java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域(Region),雖然還保留新生代和老年代的概念,但新生代和老年代不再是物理隔閡了,他們都是一部分(可以不連續(xù))Region的集合

G1的新生代收集器跟ParNew類似,當(dāng)新生代占用達(dá)到一定的比例的時(shí)候,開始觸發(fā)收集

和CMS類似,G1收集器收集老年代對(duì)象的時(shí)候會(huì)有短暫停頓

收集步驟如下 :

標(biāo)記階段 :

首先初始標(biāo)記(initial mark),這個(gè)階段是停頓的(Stop the world event),并且會(huì)觸發(fā)一次普通的Mintor GC(從年輕代空間回收)

Root Region Scanning :

運(yùn)行程序過程中會(huì)回收survivor區(qū)(存活到老年代),這一過程必須在young GC之前完成

Concurrent Marking :

在整個(gè)java堆中進(jìn)行并發(fā)標(biāo)記(和應(yīng)用程序并發(fā)執(zhí)行),此過程可能會(huì)被young GC中斷

若發(fā)現(xiàn)區(qū)域?qū)ο笾械乃袑?duì)象都是垃圾,那個(gè)區(qū)域就會(huì)被立即回收

同時(shí),并發(fā)標(biāo)記過程中,會(huì)去計(jì)算每個(gè)區(qū)域的對(duì)象活性(區(qū)域中存活對(duì)象的比例)

Remark :

再標(biāo)記,會(huì)有短暫停頓(STW)

是用來收集并發(fā)標(biāo)記階段,產(chǎn)生新的垃圾(并發(fā)階段和應(yīng)用程序一同執(zhí)行)

G1中采用了比CMS更快的初始快照算法 : snapshot-at-the-beginning (SATB)

Copy / Clean up :

多線程清除失活對(duì)象,會(huì)有STW

G1將回收區(qū)域的存活對(duì)象拷貝到新的區(qū)域,清除Remember Sets,并發(fā)清空回收區(qū)域,并把它返回到空閑的區(qū)域鏈表中

復(fù)制/清除過程后 :

回收區(qū)域的活性對(duì)象已經(jīng)被收集器回收到"最近復(fù)制的年輕代"(recently copied in young generation)和"最近復(fù)制的老年代"(recently copied in old generation)區(qū)域中了

參考文獻(xiàn)

<<深入理解JVM虛擬機(jī)>>

結(jié)束

本文提到的點(diǎn)很多,有對(duì)象引用,如何定義垃圾對(duì)象,gc算法,現(xiàn)有的垃圾收集器,等.

由于篇幅和時(shí)間原因,每個(gè)點(diǎn)都提及的不深入(當(dāng)然,本篇文章的每個(gè)點(diǎn)深入的聊起來,都?jí)驅(qū)懕緯牧?呵呵).

后續(xù)會(huì)找機(jī)會(huì)逐個(gè)的將這些點(diǎn)跟大家深入的討論.

總之 "學(xué)無止境" , 與大家共勉 .

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市崎场,隨后出現(xiàn)的幾起案子佩耳,更是在濱河造成了極大的恐慌,老刑警劉巖谭跨,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件干厚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡螃宙,警方通過查閱死者的電腦和手機(jī)蛮瞄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谆扎,“玉大人挂捅,你說我怎么就攤上這事√煤” “怎么了闲先?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)无蜂。 經(jīng)常有香客問我伺糠,道長(zhǎng),這世上最難降的妖魔是什么斥季? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任训桶,我火速辦了婚禮,結(jié)果婚禮上泻肯,老公的妹妹穿的比我還像新娘渊迁。我一直安慰自己,他們只是感情好灶挟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布琉朽。 她就那樣靜靜地躺著,像睡著了一般稚铣。 火紅的嫁衣襯著肌膚如雪箱叁。 梳的紋絲不亂的頭發(fā)上墅垮,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音耕漱,去河邊找鬼算色。 笑死,一個(gè)胖子當(dāng)著我的面吹牛螟够,可吹牛的內(nèi)容都是我干的灾梦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妓笙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼若河!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寞宫,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤萧福,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后辈赋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲫忍,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年钥屈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悟民。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篷就,死狀恐怖逾雄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腻脏,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布银锻,位于F島的核電站永品,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏击纬。R本人自食惡果不足惜鼎姐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望更振。 院中可真熱鬧炕桨,春花似錦、人聲如沸肯腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实撒。三九已至姊途,卻和暖如春涉瘾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捷兰。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工立叛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贡茅。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓秘蛇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親顶考。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赁还,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容