Java堆內(nèi)存與GC

  • 前言

開設(shè)JVM系列以后,就一直打算寫寫GC這塊的事情咙轩《笮總體上來說這塊也算是比較偏理論申鱼,很多時(shí)候是看的時(shí)候理解了愤诱,一段時(shí)間以后又忘記了,所以打算不僅寫寫理論還會(huì)寫上一些調(diào)優(yōu)的相關(guān)例子捐友,這樣會(huì)加深印象淫半。

  • 堆內(nèi)存區(qū)域劃分

我們由GC的角度來進(jìn)行堆內(nèi)存的區(qū)域劃分:新生代老年代。而新生代又可以劃分為Eden區(qū)楚殿、SurvivorFrom區(qū)撮慨、SurvivorTo區(qū)竿痰。而整個(gè)區(qū)域的比例應(yīng)該是新生代比老年代為1:2脆粥,而Eden比SurvivorFrom比SurvivorTo為8:1:1

堆內(nèi)存區(qū)域劃分.png

說完堆內(nèi)存的區(qū)域劃分以后影涉,我們?cè)俳o出關(guān)于設(shè)置堆內(nèi)存的相關(guān)參數(shù)大小的VM命令:

VM堆的相關(guān)參數(shù) 描述
-Xms 設(shè)置JVM啟動(dòng)時(shí)堆的初始化內(nèi)存大小
-Xmx 設(shè)置JVM的堆最大可用內(nèi)存大小
-Xmn 設(shè)置新生代的空間大小变隔,剩下的為老年代的空間大小(-Xmn 是將NewSize與MaxNewSize設(shè)為一致)同下面兩個(gè)參數(shù)-XX:NewSize=XXXm與-XX:MaxNewSize=XXXm
-XX:PermGen 設(shè)置永久代內(nèi)存的初始化大行非恪(1.8以后就沒有永久代了匣缘,用元數(shù)據(jù)空間代替)
-XX:MaxPermGen 設(shè)置永久代的最大值(1.8以后就沒有永久代了,用元數(shù)據(jù)空間代替)
-XX:MetaspaceSize 元數(shù)據(jù)空間初始化大小
-XX:MaxMetaspaceSize 元數(shù)據(jù)空間最大
-XX:SurvivorRatio 提供Eden區(qū)和survivor區(qū)的空間比例鲜棠。比如肌厨,如果年輕代的大小為10m并且VM參數(shù)是-XX:SurvivorRatio=2,那么將會(huì)保留5m內(nèi)存給Eden區(qū)和每個(gè)Survivor區(qū)分配2.5m內(nèi)存豁陆。默認(rèn)比例是8
-XX:NewRatio 提供年老代和年輕代的比例大小柑爸。默認(rèn)值是2
-Xss Stack(棧)內(nèi)存大小設(shè)置(每個(gè)線程都會(huì)產(chǎn)生一個(gè)棧。在相同物理內(nèi)存下盒音,減小這個(gè)值能生成更多的線程表鳍。如果這個(gè)值太小會(huì)影響方法調(diào)用的深度)
-XX:MaxTenuringThreshold 設(shè)置新生代代對(duì)象進(jìn)入老年代的年齡(設(shè)置垃圾最大年齡。如果設(shè)置為0的話祥诽,則新生代對(duì)象不經(jīng)過Survivor區(qū)譬圣,直接進(jìn)入老年代。對(duì)于老年代比較多的應(yīng)用雄坪,可以提高效率厘熟。如果將此值設(shè)置為一個(gè)較大值,則新生代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制维哈,這樣可以增加對(duì)象再新生代的存活時(shí)間绳姨,增加在新生代即被回收的概論)

通過上面的參數(shù)命令,大家可以嘗試的進(jìn)行相關(guān)JVM的內(nèi)存設(shè)置笨农,然后根據(jù)不同的設(shè)置來模擬各種OOM的情況就缆。


  • 對(duì)象在內(nèi)存中的分配
1.對(duì)象被創(chuàng)建以后,進(jìn)行內(nèi)存分配的流程

首先會(huì)嘗試是否能直接分配到棧上空間(這個(gè)跟JIT的逃逸分析有關(guān))谒亦,如果不能則再次嘗試能否分配到TLAB上(本地線程分配緩沖區(qū)竭宰,存在與Eden區(qū)域),如果不能則對(duì)對(duì)象進(jìn)行大小判斷空郊,如果是大對(duì)象(指的是占據(jù)了一個(gè)大量的連續(xù)內(nèi)存空間的對(duì)象,如數(shù)組)則直接進(jìn)入老年代如果不是大對(duì)象則直接進(jìn)入新生代里的Eden區(qū)域切揭。

關(guān)于本地線程緩沖分配區(qū)域(TLAB)

由于堆內(nèi)存是線程共享區(qū)域狞甚,在每次為對(duì)象進(jìn)行內(nèi)存空間分配的時(shí)候需要加鎖操作,可以知道的是這個(gè)操作的開銷是比較大的廓旬。所以針對(duì)這種情況哼审,Sun Hotspot JVM為了提高對(duì)象內(nèi)存分配效率,會(huì)為每個(gè)線程在堆內(nèi)存區(qū)域開辟一個(gè)專屬各個(gè)線程的緩存分配區(qū)域(Thread Local Allocation Buffer)孕豹,在這個(gè)區(qū)域進(jìn)行對(duì)象內(nèi)存分配的時(shí)候是不用加鎖的涩盾,所以效率都是很高的。但如果對(duì)象過大的話則仍然是直接使用堆空間分配励背。TLAB僅作用于新生代的Eden Space春霍,因此在編寫Java程序時(shí),通常多個(gè)小的對(duì)象比大的對(duì)象分配起來更加高效叶眉。

2. 幾種內(nèi)存分配策略
  • 對(duì)象優(yōu)先被分配到Eden區(qū)域
  • 如果是大對(duì)象址儒,則直接分配到老年代區(qū)
  • 根據(jù)對(duì)象的年齡(每經(jīng)歷一次GC,則存活下來的對(duì)象的年齡+1)衅疙,如果年齡超過標(biāo)準(zhǔn)(默認(rèn)是15)莲趣,則對(duì)象進(jìn)入老年代。
  • Survivor區(qū)域里的相同年齡數(shù)的對(duì)象數(shù)量超過了Survivor區(qū)域里可容納對(duì)象的數(shù)量的一半饱溢,則該些對(duì)象進(jìn)入老年代喧伞。
  • 對(duì)象分配空間擔(dān)保機(jī)制
    在執(zhí)行一次minorGC的時(shí)候會(huì)檢查一下老年代連續(xù)可用的內(nèi)存空間是否大于新生代所有對(duì)象的大小(防止新生代全部晉升對(duì)象到老年代),如果大于則表示本次minorGC是安全的理朋。如果不是絮识,則會(huì)進(jìn)行一次預(yù)測(cè),根據(jù)以往minorGC結(jié)束后新生代活下來的對(duì)象的平均數(shù)大小是否超過了老年代最大連續(xù)空閑空間嗽上,如果沒超過則表示雖然minorGC有風(fēng)險(xiǎn)但是還會(huì)執(zhí)行次舌,如果超過了則啟動(dòng)majorGC(fullGC)對(duì)老年代進(jìn)行GC回收騰出空間以方便給新生代做空間擔(dān)保。

分配擔(dān)保是老年代為新生代作擔(dān)保兽愤。由于新生代中使用“復(fù)制”算法實(shí)現(xiàn)垃圾回收彼念,老年代中使用“標(biāo)記-清除”或“標(biāo)記-整理”算法實(shí)現(xiàn)垃圾回收,只有使用“復(fù)制”算法的區(qū)域才需要分配擔(dān)保浅萧,因此新生代需要分配擔(dān)保逐沙,而老年代不需要分配擔(dān)保。

3. 對(duì)象內(nèi)存分配的倆種方法

為對(duì)象進(jìn)行內(nèi)存空間分配的任務(wù)洼畅,其實(shí)就是將一塊確定大小的內(nèi)存空間劃走一片吩案。

  • 指針碰撞
    假設(shè)Java堆中內(nèi)存是絕對(duì)規(guī)整的,所有用過的內(nèi)存都放在一邊帝簇,空閑的內(nèi)存放在另一邊徘郭,中間放著一個(gè)指針作為分界點(diǎn)的指示器靠益,那所分配內(nèi)存就僅僅是把那個(gè)指針向空閑空間那邊挪動(dòng)一段與對(duì)象大小相等的距離,這種分配方式稱為“指針碰撞”(Bump the Pointer)

  • 空閑列表
    (CMS這種基于Mark-Sweep算法的收集器) 如果Java堆中的內(nèi)存并不是規(guī)整的残揉,已使用的內(nèi)存和空閑的內(nèi)存相互交錯(cuò)胧后,那就沒有辦法簡(jiǎn)單地進(jìn)行指針碰撞了,虛擬機(jī)就必須維護(hù)一個(gè)列表抱环,記錄上哪些內(nèi)存塊是可用的壳快,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對(duì)象實(shí)例,并更新列表上的記錄镇草,這種分配方式稱為“空閑列表”(Free List)眶痰。

選擇哪種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定陶夜。因此凛驮,在使用Serial裆站、ParNew等帶Compact過程的收集器時(shí)条辟,系統(tǒng)采用的分配算法是指針碰撞,而使用CMS這種基于Mark-Sweep算法的收集器時(shí)宏胯,通常采用空閑列表


  • 關(guān)于GC

什么是GC羽嫡?字面意思解釋就是垃圾回收。在我們Java里面肩袍,當(dāng)對(duì)象創(chuàng)建好以后杭棵,我們是不需要關(guān)心對(duì)象的回收工作的,由JVM虛擬機(jī)會(huì)自動(dòng)幫我們?nèi)セ厥者@些對(duì)象氛赐,而JVM能這樣做的原因就是因?yàn)檫@個(gè)GC垃圾回收機(jī)制魂爪。

1. 確定對(duì)象為垃圾的2種算法
  • 引用計(jì)數(shù)法
    Jvm會(huì)為每個(gè)對(duì)象進(jìn)行引用計(jì)數(shù),如果一個(gè)對(duì)象被引用了這計(jì)數(shù)加1艰管,如果該引用被釋放了滓侍,則計(jì)數(shù)減1,當(dāng)計(jì)數(shù)為0的時(shí)候則表示該對(duì)象可以被回收牲芋。缺點(diǎn):無法識(shí)別循環(huán)引用的對(duì)象撩笆。
    給出例子:
public class ReferenceCountingGC {
    public Object instance;
    public ReferenceCountingGC(String name){}
}

public static void testGC(){

    ReferenceCountingGC a = new ReferenceCountingGC("objA");
    ReferenceCountingGC b = new ReferenceCountingGC("objB");

    a.instance = b;
    b.instance = a;

    a = null;
    b = null;
}

1. 定義2個(gè)對(duì)象
2. 相互引用
3. 置空各自的聲明引用

循環(huán)引用.png

我們可以看到,最后這2個(gè)對(duì)象已經(jīng)不可能再被訪問了缸浦,但由于他們相互引用著對(duì)方夕冲,導(dǎo)致它們的引用計(jì)數(shù)永遠(yuǎn)都不會(huì)為0,通過引用計(jì)數(shù)算法裂逐,也就永遠(yuǎn)無法通知GC收集器回收它們歹鱼。

  • 可達(dá)性分析算法
    根據(jù)GCroots來作為探索起點(diǎn)來探索到對(duì)象之間是否有可到達(dá)的路徑,如果沒有路徑這表示該對(duì)象是不可達(dá)(不可達(dá)對(duì)象不代表是可回收對(duì)象在這之間會(huì)有倆次標(biāo)記過程卜高,倆次標(biāo)記以后任然是可回收對(duì)象則才是可回收對(duì)象)


    可達(dá)性算法.png

哪些是GC roots弥姻?
根據(jù)JVM規(guī)定只有虛擬機(jī)方法棧上和本地方法棧上引用的對(duì)象和方法區(qū)中類的靜態(tài)屬性引用的對(duì)象以及方法區(qū)中常量引用的對(duì)象

如何找到GC roots秩霍?
通過采用一個(gè)OopMap的數(shù)據(jù)結(jié)構(gòu)來記錄系統(tǒng)中存活的“GC Roots”,在類加載完成的時(shí)候蚁阳,虛擬機(jī)就把對(duì)象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)計(jì)算出來保存在OopMap铃绒,通過OopMap就可以找到堆中的對(duì)象,這些對(duì)象就是GC Roots螺捐。而不需要一個(gè)一個(gè)的去判斷某個(gè)內(nèi)存位置的值是不是引用颠悬。這種方式也叫準(zhǔn)確式GC

2. GC的分類

GC可以被劃分為minorGCmajorGC。第一個(gè)是用來處理新生代區(qū)內(nèi)的對(duì)象回收的GC定血,第二個(gè)是用來處理老年代和永久代(jdk8以后就沒有永久代了)區(qū)內(nèi)的對(duì)象回收的GC赔癌。至于Full GC網(wǎng)上眾說紛壇我看了好幾篇博客大概感覺fullGC應(yīng)該可以理解為minorGC+majorGC。

堆內(nèi)存中何時(shí)觸發(fā)GC進(jìn)行工作的澜沟?
minorGC 當(dāng)Eden區(qū)的大小滿了以后會(huì)觸發(fā)minorGC來進(jìn)行工作灾票;
majorGC 當(dāng)old區(qū)滿了以后會(huì)觸發(fā)majorGC來清理old區(qū)的對(duì)象,或者當(dāng)老年代無法為新生代提供空間擔(dān)保的時(shí)候則會(huì)觸發(fā)majorGC來清理老年代對(duì)象為新生代騰出空間茫虽。

3. 垃圾回收算法
  • 標(biāo)記清除算法(mark-sweep)
    最基礎(chǔ)的回收算法刊苍,在標(biāo)記階段對(duì)可回收對(duì)象進(jìn)行標(biāo)記,在清除階段對(duì)被標(biāo)記的對(duì)象所占空間進(jìn)行回收濒析。缺點(diǎn):內(nèi)存碎片化嚴(yán)重正什,可能會(huì)導(dǎo)致大的對(duì)象找不到內(nèi)存空間
  • 復(fù)制算法(coping)
    將內(nèi)存空間分為大小相等的倆塊,當(dāng)其中一塊內(nèi)存空間已經(jīng)滿了的時(shí)候号杏,將不可回收的對(duì)象復(fù)制到另一塊內(nèi)存空間中婴氮,然后將原先滿了的內(nèi)存空間清理干凈,再次使用內(nèi)存空間進(jìn)行分配的時(shí)候就使用另一塊內(nèi)存空間盾致。這樣的好處是避免了上述算法會(huì)產(chǎn)生大量的內(nèi)存碎片空間主经,缺點(diǎn):每次只能使用一半的內(nèi)存,而且如果存活對(duì)象比較多的情況會(huì)導(dǎo)致復(fù)制算法效率下降(大量的存活對(duì)象需要進(jìn)行復(fù)制遷移)

  • 標(biāo)記壓縮算法(mark-compact)
    綜合以上倆種方法的缺陷庭惜,提出第三種回收算法罩驻,標(biāo)記階段與標(biāo)記清除算法是差不多的,然后標(biāo)記結(jié)束不是立即回收蜈块,而是將存活的對(duì)象移動(dòng)到內(nèi)存的一端鉴腻,然后再清除端邊界外的對(duì)象。好處:解決了上述倆種方法的內(nèi)存空間碎片化嚴(yán)重百揭、內(nèi)存空間利用不足的問題爽哎。

  • 分代收集算法
    分代收集法是目前大部分 JVM 所采用的方法,老年代的特點(diǎn)是每次垃圾回收時(shí)只有少量對(duì)象需要被回收器一,新生代的特點(diǎn)是每次垃圾回收時(shí)都有大量垃圾需要被回收课锌,因此可以根據(jù)不同區(qū)域選擇不同的算法。新生代都采取復(fù)制算法,老年代采取標(biāo)記壓縮算法渺贤。

為什么堆內(nèi)存要分區(qū)雏胃?
是為了更好的對(duì)堆內(nèi)對(duì)象進(jìn)行回收工作,在新生代中針對(duì)對(duì)象的朝生夕死特性志鞍,選擇使用復(fù)制算法來進(jìn)行GC工作瞭亮,因?yàn)榇婊畹膶?duì)象少所以復(fù)制算法的效率很高。在老年代中采用的是標(biāo)記壓縮法來進(jìn)行固棚,因?yàn)榇婊畹膶?duì)象比較多如果采用復(fù)制算法則會(huì)導(dǎo)致效率很低统翩。

4. 幾種垃圾收集器
  • Serial收集器(新生代的垃圾收集器)
    單線程、采用復(fù)制算法的垃圾收集器此洲。它不但只會(huì)使用一個(gè) CPU 或一條線程去完成垃圾收集工作厂汗,并且在進(jìn)行垃圾收集的同時(shí),必須暫停其他所有的工作線程(STOP THE WORLD)呜师,直到垃圾收集結(jié)束娶桦。
    Serial 垃圾收集器雖然在收集垃圾過程中需要暫停所有其他的工作線程,但是它簡(jiǎn)單高效汁汗,是jvm運(yùn)行在client模式下的默認(rèn)采用的新生代垃圾收集器衷畦。
    通過-XX:+UseSerialGC參數(shù)啟用
  • ParNew收集器(新生代的垃圾收集器)
    與serial垃圾收集器唯一的不同在于它是多線程下的采用復(fù)制算法的垃圾收集器。但對(duì)于單核的設(shè)備來說碰酝,需要進(jìn)行線程之間的切換霎匈,效率反而沒有單線程的高。默認(rèn)開啟的線程數(shù)等于cpu的數(shù)量送爸。Jvm運(yùn)行在server模式下默認(rèn)采用的新生代垃圾收集器。
    通過-XX:ParallelGCThreads參數(shù)限制收集的線程數(shù)暖释,-XX:+UseParNewGC參數(shù)啟用

  • Parallel Scavenge收集器(新生代的垃圾收集器)
    與PN相同的是袭厂,同樣使用復(fù)制算法,也是一個(gè)多線程的垃圾收集器球匕。與PN不同點(diǎn)在于它關(guān)注程序是否到達(dá)了一個(gè)可控制的吞吐量(CPU計(jì)算用戶代碼消耗時(shí)間/cpu總消耗時(shí)間)主要追求高效的CPU計(jì)算纹磺,追求快速完成計(jì)算任務(wù)。(適用于在后臺(tái)運(yùn)算不需要太多交互的任務(wù))
    通過參數(shù)-XX:MaxGCPauseMillis設(shè)置最大GC的停頓時(shí)間和-XX:GCTimeRatio 設(shè)置吞吐量的大小亮曹。-XX:+UseParallelGC參數(shù)啟用

另外橄杨,可以通過-XX:+UseAdaptiveSizePolicy參數(shù)開啟自適應(yīng)調(diào)節(jié)策略,這樣可以免去我們自己設(shè)置堆內(nèi)存的一些細(xì)節(jié)參數(shù)照卦,比如新生代內(nèi)存大小式矫,Eden與Survivor之間的比例等等。這個(gè)參數(shù)適合對(duì)內(nèi)存手工優(yōu)化存在困難的時(shí)候使用役耕,他能監(jiān)控系統(tǒng)當(dāng)前的狀態(tài)采转,動(dòng)態(tài)的調(diào)整以達(dá)到最大的吞吐量

  • Serial Old垃圾收集器(老年代的垃圾收集器)
    單線程下采用標(biāo)記整理算法來實(shí)現(xiàn)。也是在client模式下使用的默認(rèn)老年代垃圾收集器瞬痘。在server模式下作為CMS并發(fā)收集模式失敗的情況下備選方案故慈。

  • Parallel Old垃圾收集器(老年代的垃圾收集器)
    是SO的多線程版本板熊。同時(shí)也保證了老年代的吞吐量與PS在新生代里保證吞吐量的功能是一致的。

  • CMS垃圾收集器(老年代的垃圾收集器)
    多線程下采用標(biāo)記清除算法來實(shí)現(xiàn)的察绷。主要是為了追求最短的回收停頓時(shí)間來快速響應(yīng)服務(wù)干签。
    步驟:
    初始標(biāo)記:需要進(jìn)行STW的,但僅僅只是標(biāo)記GC Roots能夠直接關(guān)聯(lián)的對(duì)象(并不是死掉的對(duì)象哦~)拆撼,由于有OopMap的存在筒严,因此該步驟速度非常快情萤。如圖鸭蛙,其中藍(lán)色底紋的便是能夠直接關(guān)聯(lián)的對(duì)象。

    初始標(biāo)記直接關(guān)聯(lián)對(duì)象.png

    并發(fā)標(biāo)記:這步是不需要STW的筋岛,不需要娶视!他和我們的主程序線程共同執(zhí)行,從上一步被標(biāo)記的對(duì)象開始睁宰,進(jìn)行可達(dá)性分析組成“關(guān)系網(wǎng)”肪获。由于不需要進(jìn)行SWT,所以該步驟不會(huì)影響用戶體驗(yàn)柒傻。既然不暫停線程孝赫,大家是不是又怕回收了不該回收的對(duì)象?為了避免這個(gè)問題红符,因此就有了第三步青柄。
    重新標(biāo)記:針對(duì)并發(fā)標(biāo)記過程中因?yàn)槌绦蚶^續(xù)運(yùn)行,導(dǎo)致標(biāo)記發(fā)生變化的那部分對(duì)象進(jìn)行標(biāo)記修正预侯,需要暫停所有的工作線程致开。
    并發(fā)清除
    清除GC roots里不可達(dá)對(duì)象,和用戶線程一起工作不需要暫停工作進(jìn)程萎馅。由于四個(gè)階段里耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除都不需要暫停工作進(jìn)程双戳,所以可以認(rèn)為CMS的垃圾回收是和用戶線程一起并發(fā)進(jìn)行的。
    優(yōu)點(diǎn):并發(fā)收集垃圾糜芳,低停頓性飒货。
    缺點(diǎn):由于采用標(biāo)記-清除算法所以會(huì)產(chǎn)生內(nèi)存碎片,對(duì)于浮動(dòng)垃圾沒辦法收集峭竣。(當(dāng)在并發(fā)清除垃圾的時(shí)候塘辅,也就是第四步的時(shí)候,他是與當(dāng)前主線程并發(fā)執(zhí)行的邪驮,因此他在回收的時(shí)候莫辨,我們的主線程又會(huì)產(chǎn)生新的垃圾,而這些垃圾在這次回收過程已經(jīng)回收不了了,只能等待下一次回收了沮榜。這些垃圾又叫做“浮動(dòng)垃圾”)

  • G1垃圾收集器(作用范圍為整個(gè)堆的垃圾收集器)
    相對(duì)于CMS垃圾收集器來說盘榨,G1收集器采用標(biāo)記-壓縮算法不會(huì)產(chǎn)生內(nèi)存碎片。而且能更加精準(zhǔn)的控制停頓時(shí)間蟆融,實(shí)現(xiàn)低停頓垃圾回收草巡。(主要是采用了分區(qū),針對(duì)每個(gè)區(qū)的垃圾收集進(jìn)度情況來在后臺(tái)維護(hù)一個(gè)優(yōu)先級(jí)列表型酥,每次根據(jù)所允許的收集時(shí)間山憨,優(yōu)先選擇垃圾回收最多的區(qū)域)通過-XX:MaxGCPauseMills設(shè)置有限的收集時(shí)間。

垃圾收集器是不能隨意組合的弥喉,現(xiàn)在給出垃圾收集器互相的組合圖:


垃圾收集器組合使用.png

至此郁竟,就把堆內(nèi)存與GC相關(guān)的東西說完了,有點(diǎn)淺顯由境,很多都是泛泛而談棚亩。后面我會(huì)專開一篇文章來實(shí)戰(zhàn)分析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虏杰,一起剝皮案震驚了整個(gè)濱河市讥蟆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纺阔,老刑警劉巖瘸彤,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異笛钝,居然都是意外死亡质况,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門婆翔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拯杠,“玉大人,你說我怎么就攤上這事啃奴。” “怎么了雄妥?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵最蕾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我老厌,道長(zhǎng)瘟则,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任枝秤,我火速辦了婚禮醋拧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己丹壕,他們只是感情好庆械,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菌赖,像睡著了一般缭乘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琉用,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天堕绩,我揣著相機(jī)與錄音,去河邊找鬼邑时。 笑死奴紧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晶丘。 我是一名探鬼主播黍氮,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铣口!你這毒婦竟也來了滤钱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤脑题,失蹤者是張志新(化名)和其女友劉穎件缸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叔遂,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡他炊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了已艰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痊末。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖哩掺,靈堂內(nèi)的尸體忽然破棺而出凿叠,到底是詐尸還是另有隱情,我是刑警寧澤嚼吞,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布盒件,位于F島的核電站,受9級(jí)特大地震影響舱禽,放射性物質(zhì)發(fā)生泄漏炒刁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一誊稚、第九天 我趴在偏房一處隱蔽的房頂上張望翔始。 院中可真熱鬧罗心,春花似錦、人聲如沸城瞎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽全谤。三九已至肤晓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間认然,已是汗流浹背补憾。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卷员,地道東北人盈匾。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像毕骡,于是被迫代替她去往敵國(guó)和親削饵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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