JVM之運(yùn)行時(shí)數(shù)據(jù)區(qū)

簡(jiǎn)介

Java虛擬機(jī)(即JVM)在Java程序運(yùn)行的過程中蚤假,會(huì)將它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域惠呼,這些區(qū)域有的隨著JVM的啟動(dòng)而創(chuàng)建崇众,有的隨著用戶線程的啟動(dòng)和結(jié)束而建立和銷毀紧憾。
除此之外反惕,JVM的內(nèi)存管理機(jī)制使得不需要再為每一個(gè)新的操作去刪除/免費(fèi)代碼,由機(jī)器代替程序員這樣就不容易出現(xiàn)內(nèi)存泄露和內(nèi)存溢出的問題了,但是一旦出現(xiàn)了這種問題如果不了解JVM是怎樣使用內(nèi)存的炕吸,那么排查錯(cuò)誤將會(huì)非常困難伐憾。一個(gè)基本的JVM運(yùn)行時(shí)內(nèi)存模型如下所示:

JDK1.7 JVM內(nèi)存模型

程序運(yùn)行時(shí)可能只有一個(gè)線程,也可能有多個(gè)線程共同執(zhí)行赫模,而方法區(qū)和堆是程序的所有線程所共享的內(nèi)存區(qū)域树肃,而程序寄存器、虛擬機(jī)棧和本地方法棧則是每個(gè)線程獨(dú)占的內(nèi)存區(qū)域瀑罗。

一胸嘴、程序計(jì)數(shù)器(Program Counter Register)

1.什么是程序計(jì)數(shù)器

程序計(jì)數(shù)器是一個(gè)記錄著當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器
  JAVA代碼編譯后的字節(jié)碼在未經(jīng)過JIT(實(shí)時(shí)編譯器)編譯前斩祭,其執(zhí)行方式是通過“字節(jié)碼解釋器”進(jìn)行解釋執(zhí)行劣像。簡(jiǎn)單的工作原理為解釋器讀取裝載入內(nèi)存的字節(jié)碼,按照順序讀取字節(jié)碼指令停忿。讀取一個(gè)指令后驾讲,將該指令“翻譯”成固定的操作,并根據(jù)這些操作進(jìn)行分支席赂、循環(huán)吮铭、跳轉(zhuǎn)等流程。
  從上面的描述中,可能會(huì)產(chǎn)生程序計(jì)數(shù)器是否是多余的疑問。因?yàn)檠刂噶畹捻樞驁?zhí)行下去顷级,即使是分支跳轉(zhuǎn)這樣的流程勺爱,跳轉(zhuǎn)到指定的指令處按順序繼續(xù)執(zhí)行是完全能夠保證程序的執(zhí)行順序的。假設(shè)程序永遠(yuǎn)只有一個(gè)線程,這個(gè)疑問沒有任何問題,也就是說并不需要程序計(jì)數(shù)器。但實(shí)際上程序是通過多個(gè)線程協(xié)同合作執(zhí)行的柏肪。
  首先我們要搞清楚JVM的多線程實(shí)現(xiàn)方式。JVM的多線程是通過CPU時(shí)間片輪轉(zhuǎn)(即線程輪流切換并分配處理器執(zhí)行時(shí)間)算法來實(shí)現(xiàn)的芥牌。也就是說烦味,某個(gè)線程在執(zhí)行過程中可能會(huì)因?yàn)闀r(shí)間片耗盡而被掛起,而另一個(gè)線程獲取到時(shí)間片開始執(zhí)行壁拉。當(dāng)被掛起的線程重新獲取到時(shí)間片的時(shí)候谬俄,它要想從被掛起的地方繼續(xù)執(zhí)行,就必須知道它上次執(zhí)行到哪個(gè)位置弃理,在JVM中溃论,通過程序計(jì)數(shù)器來記錄某個(gè)線程的字節(jié)碼執(zhí)行位置。因此痘昌,程序計(jì)數(shù)器是具備線程隔離的特性钥勋,也就是說炬转,每個(gè)線程工作時(shí)都有屬于自己的獨(dú)立計(jì)數(shù)器。

2.程序計(jì)數(shù)器的特點(diǎn)
  • 線程隔離性算灸,每個(gè)線程工作時(shí)都有屬于自己的獨(dú)立計(jì)數(shù)器返吻,即程序計(jì)數(shù)器是線程私有的
  • 執(zhí)行Java方法時(shí),程序計(jì)數(shù)器是有值的乎婿,且記錄的是正在執(zhí)行的字節(jié)碼指令的地址
  • 執(zhí)行native本地方法時(shí),程序計(jì)數(shù)器的值為空(Undefined)街佑。因?yàn)閚ative方法是java通過JNI直接調(diào)用本地C/C++庫谢翎,可以近似的認(rèn)為native方法相當(dāng)于C/C++暴露給java的一個(gè)接口,java通過調(diào)用這個(gè)接口從而調(diào)用到C/C++方法沐旨。由于該方法是通過C/C++而不是java進(jìn)行實(shí)現(xiàn)森逮。那么自然無法產(chǎn)生相應(yīng)的字節(jié)碼,并且C/C++執(zhí)行時(shí)的內(nèi)存分配是由自己語言決定的磁携,而不是由JVM決定的褒侧。
  • 程序計(jì)數(shù)器占用內(nèi)存很小,在進(jìn)行JVM內(nèi)存計(jì)算時(shí)谊迄,可以忽略不計(jì)闷供。
  • 程序計(jì)數(shù)器,是唯一一個(gè)在java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError的區(qū)域统诺。

二歪脏、Java虛擬機(jī)棧(VM Stack)

1、什么是Java虛擬機(jī)棧
  • 用于作用于方法執(zhí)行的一塊Java內(nèi)存區(qū)域
  • 虛擬機(jī)棧是用于描述java方法執(zhí)行的內(nèi)存模型粮呢。
  • 每個(gè)java方法在執(zhí)行時(shí)婿失,會(huì)創(chuàng)建一個(gè)“棧幀(stack frame)”,棧幀的結(jié)構(gòu)分為“局部變量表啄寡、操作數(shù)棧豪硅、動(dòng)態(tài)鏈接、方法出口”幾個(gè)部分(具體的作用會(huì)在字節(jié)碼執(zhí)行引擎章節(jié)中講到挺物,這里只需要了解棧幀是一個(gè)方法執(zhí)行時(shí)所需要數(shù)據(jù)的結(jié)構(gòu))
2懒浮、特點(diǎn)
  • Java虛擬機(jī)棧也是線程私有的,它的生命周期與線程相同(隨線程而生姻乓,隨線程而滅)

  • 如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度嵌溢,將拋出StackOverflowError異常

  • 如果虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展蹋岩,如果擴(kuò)展時(shí)無法申請(qǐng)到足夠的內(nèi)存赖草,就會(huì)拋出OutOfMemoryError異常

  • Java虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法執(zhí)行的同時(shí)會(huì)創(chuàng)建一個(gè)棧幀

  • 對(duì)于我們來說,主要關(guān)注的stack棧內(nèi)存剪个,就是虛擬機(jī)棧中局部變量表部分秧骑。

3、棧幀
虛擬機(jī)棧結(jié)構(gòu)圖
  • 棧幀(Stack Frame)是用于支持虛擬機(jī)進(jìn)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),它是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)中的java虛擬機(jī)棧的棧元素乎折。
  • 棧幀存儲(chǔ)了方法的局部變量表绒疗、操作數(shù)棧、動(dòng)態(tài)連接和方法返回地址等信息
  • 每一個(gè)方法從調(diào)用開始至執(zhí)行完成的過程骂澄,都對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)里面從入棧到出棧的過程
    注意
    在編譯程序代碼的時(shí)候吓蘑,棧幀中需要多大的局部變量表內(nèi)存,多深的操作數(shù)棧都已經(jīng)完全確定了坟冲。
    因此一個(gè)棧幀需要分配多少內(nèi)存磨镶,不會(huì)受到程序運(yùn)行期變量數(shù)據(jù)的影響,而僅僅取決于具體的虛擬機(jī)實(shí)現(xiàn)健提。
    #######棧幀結(jié)構(gòu)如下:
4琳猫、局部變量表
1.局部變量表(Local Variable Table)是一組變量值存儲(chǔ)空間,用于存放方法參數(shù)和方法內(nèi)部定義的局部變量私痹。并且在Java編譯為Class文件時(shí)脐嫂,就已經(jīng)確定了該方法所需要分配的局部變量表的最大容量。
2.局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean紊遵、byte账千、char、short暗膜、int蕊爵、float、long桦山、double)「String是引用類型」攒射,對(duì)象引用(reference類型) 和 returnAddress類型(它指向了一條字節(jié)碼指令的地址)

注意
很多人說:基本數(shù)據(jù)和對(duì)象引用存儲(chǔ)在棧中。
當(dāng)然這種說法雖然是正確的恒水,但是很不嚴(yán)謹(jǐn)会放,只能說這種說法針對(duì)的是局部變量。
局部變量存儲(chǔ)在局部變量表中钉凌,隨著線程而生咧最,線程而滅。并且線程間數(shù)據(jù)不共享御雕。但是矢沿,如果是成員變量,或者定義在方法外對(duì)象的引用酸纲,它們存儲(chǔ)在堆中捣鲸。
因?yàn)樵诙阎校蔷€程共享數(shù)據(jù)的闽坡,并且棧幀里的命名就已經(jīng)清楚的劃分了界限 : 局部變量表栽惶!

5愁溜、reference(對(duì)象實(shí)例的引用)

個(gè)人感覺和指針類似
一般來說,虛擬機(jī)都能從引用中直接或者間接的查找到對(duì)象的以下兩點(diǎn) :
a.在Java堆中的數(shù)據(jù)存放的起始地址索引外厂。
b.所屬數(shù)據(jù)類型在方法區(qū)中的存儲(chǔ)類型冕象。
例如:我們?cè)趧?chuàng)建一個(gè)Student對(duì)象時(shí)的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu):

6、案例

來段代碼試求程序運(yùn)行時(shí)虛擬機(jī)棧的內(nèi)存長度汁蝶,拋出StackOverflowError異常

package yzl.swu.practice;

 /** 測(cè)試代碼設(shè)計(jì)思路
 * 修改默認(rèn)堆棧大小后,利用遞歸調(diào)用一個(gè)方法,達(dá)到棧深度過大的異常目的,同時(shí)在遞歸調(diào)用過程中記錄調(diào)用此次,得出最大深度的數(shù)據(jù)
 * jvm參數(shù)
 * -Xss 180k:設(shè)置每個(gè)線程的堆棧大小(最小180k),默認(rèn)是1M
 */
public class TestStackOverflowErrorDemo {
    //棧深度統(tǒng)計(jì)值
    private int stackLength = 1;

    /**
     * 遞歸方法,導(dǎo)致棧深度過大異常
     */
    public void stackLeak() {
        stackLength++;
        stackLeak();
    }

    /**
     * 啟動(dòng)方法
     * 測(cè)試結(jié)果:當(dāng)-Xss 180k為180k時(shí),stackLength~=1544,隨著-Xss參數(shù)變大時(shí)stackLength值隨之變大
     * @param args
     */
    public static void main(String[] args) {
        TestStackOverflowErrorDemo demo = new TestStackOverflowErrorDemo();
        try {
            demo.stackLeak();
        } catch (Throwable e) {
            System.out.println("當(dāng)前棧深度:stackLength=" + demo.stackLength);
            e.printStackTrace();
        }
    }
}

三渐扮、本地方法棧(Native Method Stack)

  • 用于作用域本地方法執(zhí)行的一塊Java內(nèi)存區(qū)域
  • 本地方法棧的功能和特點(diǎn)類似于虛擬機(jī)棧,均具有線程隔離的特點(diǎn)以及都能拋出StackOverflowError和OutOfMemoryError異常掖棉。
  • 不同的是席爽,本地方法棧服務(wù)的對(duì)象是JVM執(zhí)行的native方法(java代碼中使用native關(guān)鍵字標(biāo)記的方法),而虛擬機(jī)棧服務(wù)的是JVM執(zhí)行的java方法啊片。如何去服務(wù)native方法?native方法使用什么語言實(shí)現(xiàn)玖像?怎么組織像棧幀這種為了服務(wù)方法的數(shù)據(jù)結(jié)構(gòu)紫谷?虛擬機(jī)規(guī)范并未給出強(qiáng)制規(guī)定,因此不同的虛擬機(jī)實(shí)可以進(jìn)行自由實(shí)現(xiàn)捐寥,我們常用的HotSpot虛擬機(jī)選擇合并了虛擬機(jī)棧和本地方法棧笤昨。

四、堆(Heap)

1握恳、什么是Java堆

對(duì)于大多數(shù)應(yīng)用來說瞒窒,堆是JVM所管理的內(nèi)存中最大的一塊,也是被所有線程共享的一塊內(nèi)存區(qū)域乡洼,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建崇裁。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存束昵,可謂是對(duì)象的大本營拔稳。此外,堆也是垃圾收集器(GC)管理的主要區(qū)域锹雏。

2巴比、堆的特點(diǎn)
  • 一個(gè)jvm實(shí)例只存在一個(gè)堆內(nèi)存,堆也是java內(nèi)存管理的核心區(qū)域
  • Java堆區(qū)在JVM啟動(dòng)的時(shí)候即被創(chuàng)建礁遵,其空間大小也就確定了轻绞。是JVM管理的最大一塊內(nèi)存空間(堆內(nèi)存的大小是可以調(diào)節(jié)的)
  • 《Java虛擬機(jī)規(guī)范》規(guī)定,堆可以處于物理上不連續(xù)的內(nèi)存空間中佣耐,但在邏輯上它應(yīng)該被視為連續(xù)的
  • 《Java虛擬機(jī)規(guī)范》中對(duì)java堆的描述是:所有的對(duì)象實(shí)例以及數(shù)組都應(yīng)當(dāng)在運(yùn)行時(shí)分配在堆上政勃。從實(shí)際使用的角度看,“幾乎”所有的對(duì)象的實(shí)例都在這里分配內(nèi)存
  • 數(shù)組或?qū)ο笥肋h(yuǎn)不會(huì)存儲(chǔ)在棧上兼砖,因?yàn)闂斜4嬉眉诓。@個(gè)引用指向?qū)ο蠡蛘邤?shù)組在堆中的位置(String也是引用對(duì)象哦)
  • 在方法結(jié)束后选侨,堆中的對(duì)象不會(huì)馬上被移除,僅僅在垃圾收集的時(shí)候才會(huì)被移除
  • 堆在邏輯上劃分為“新生代”和“老年代”然走。由于JAVA中的對(duì)象大部分是朝生夕滅援制,還有一小部分能夠長期的駐留在內(nèi)存中,為了對(duì)這兩種對(duì)象進(jìn)行最有效的回收芍瑞,將堆劃分為新生代和老年代晨仑,并且執(zhí)行不同的回收策略。不同的垃圾收集器對(duì)這2個(gè)邏輯區(qū)域的回收機(jī)制不盡相同拆檬。
3洪己、堆的OutOfMemoryError異常
  • 當(dāng)堆無法分配對(duì)象內(nèi)存且無法再擴(kuò)展時(shí),會(huì)拋出OutOfMemoryError異常竟贯。
  • 一般來說答捕,堆無法分配對(duì)象時(shí)會(huì)進(jìn)行一次GC,如果GC后仍然無法分配對(duì)象屑那,才會(huì)報(bào)內(nèi)存耗盡的錯(cuò)誤拱镐。
    代碼測(cè)試一下:
public class Test {
    public static void main(String[] args) {
        List list = new ArrayList();
        while (true) {
            //重復(fù)的向list內(nèi)添加1MB大小的數(shù)據(jù),由于list內(nèi)元素不符合GC回收條件進(jìn)而導(dǎo)致OOM持际。
            list.add(new byte[1024 * 1024]);
        }
    } 
}

五沃琅、Java方法區(qū)(Method Area)

1、什么是Java方法區(qū)

方法區(qū)蜘欲,也稱非堆(Non-Heap益眉,與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域姥份,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息郭脂、常量、靜態(tài)變量澈歉、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)朱庆。
方法區(qū)結(jié)構(gòu)圖如下:

2、運(yùn)行時(shí)常量池

首先需要知道常量池和運(yùn)行時(shí)常量池的區(qū)別闷祥。

  • 常量池
    即指class文件常量池娱颊,是class文件的一部分。java文件被編譯成class文件之后凯砍,除了包含了類的版本箱硕、字段、方法悟衩、接口等描述信息剧罩,還有一項(xiàng)信息叫做class文件常量池。其用于存放編譯期生成的各種字面量和符號(hào)引用座泳。
  • 運(yùn)行時(shí)常量池
    Java語言并不要求常量一定只能在編譯期產(chǎn)生惠昔,運(yùn)行期間也可能產(chǎn)生新的常量幕与,這些常量被放在運(yùn)行時(shí)常量池中。
    類加載后镇防,常量池中的數(shù)據(jù)會(huì)在運(yùn)行時(shí)常量池中存放啦鸣!
    這里所說的常量包括:基本類型包裝類(包裝類不管理浮點(diǎn)型,整形只會(huì)管理-128到127)和String(也可以通過String.intern()方法可以強(qiáng)制將String放入常量池)
  • 字符串常量池
    HotSpot VM里来氧,記錄interned string的一個(gè)全局表叫做StringTable诫给,它本質(zhì)上就是個(gè)HashSet<String>。注意它只存儲(chǔ)對(duì)java.lang.String實(shí)例的引用啦扬,而不存儲(chǔ)String對(duì)象的內(nèi)容
注意:jdk 1.7后中狂,移除了方法區(qū)間,運(yùn)行時(shí)常量池和字符串常量池都在堆中扑毡。
3胃榕、方法區(qū)的實(shí)現(xiàn)

具體放在哪里,不同的實(shí)現(xiàn)可以放在不同的地方瞄摊。永久代是HotSpot虛擬機(jī)特有的概念勋又,是對(duì)方法區(qū)的實(shí)現(xiàn),別的JVM沒有永久代的概念泉褐。(雖然去除了永久代,但是方法區(qū)作為概念上的區(qū)域仍然存在)
方法區(qū)的實(shí)現(xiàn)鸟蜡,虛擬機(jī)規(guī)范中并未明確規(guī)定膜赃,目前有2種比較主流的實(shí)現(xiàn)方式:

  • HotSpot虛擬機(jī)1.7-:在JDK1.6及之前版本,HotSpot使用“永久代(permanent generation)”的概念作為實(shí)現(xiàn)揉忘,即將GC分代收集擴(kuò)展至方法區(qū)跳座。這種實(shí)現(xiàn)比較偷懶,可以不必為方法區(qū)編寫專門的內(nèi)存管理泣矛,但帶來的后果是容易碰到內(nèi)存溢出的問題(因?yàn)橛谰么?XX:MaxPermSize的上限)疲眷。在JDK1.7+之后,HotSpot逐漸改變方法區(qū)的實(shí)現(xiàn)方式您朽,如1.7版本移除了方法區(qū)中的字符串常量池狂丝。
  • HotSpot虛擬機(jī)1.8+:1.8版本中移除了方法區(qū)并使用metaspace(元數(shù)據(jù)空間)作為替代實(shí)現(xiàn)。metaspace占用系統(tǒng)內(nèi)存哗总,也就是說几颜,只要不碰觸到系統(tǒng)內(nèi)存上限,方法區(qū)會(huì)有足夠的內(nèi)存空間讯屈。但這不意味著我們不對(duì)方法區(qū)進(jìn)行限制蛋哭,如果方法區(qū)無限膨脹,最終會(huì)導(dǎo)致系統(tǒng)崩潰涮母。
    JDK1.8+ JVM
4谆趾、方法區(qū)的OutOfMemoryError
  • 首先躁愿,為什么使用“永久代”并將GC分代收集擴(kuò)展至方法區(qū)這種實(shí)現(xiàn)方式不好,會(huì)導(dǎo)致OOM沪蓬?首先要明白方法區(qū)的內(nèi)存回收目標(biāo)是什么彤钟,方法區(qū)存儲(chǔ)了類的元數(shù)據(jù)信息和各種常量,它的內(nèi)存回收目標(biāo)理應(yīng)當(dāng)是對(duì)這些類型的卸載和常量的回收怜跑。但由于這些數(shù)據(jù)被類的實(shí)例引用样勃,卸載條件變得復(fù)雜且嚴(yán)格,回收不當(dāng)會(huì)導(dǎo)致堆中的類實(shí)例失去元數(shù)據(jù)信息和常量信息性芬。因此峡眶,回收方法區(qū)內(nèi)存不是一件簡(jiǎn)單高效的事情,往往GC在做無用功植锉。另外隨著應(yīng)用規(guī)模的變大辫樱,各種框架的引入,尤其是使用了字節(jié)碼生成技術(shù)的框架俊庇,會(huì)導(dǎo)致方法區(qū)內(nèi)存占用越來越大狮暑,最終OOM。
  • 因?yàn)榉椒▍^(qū)最終都會(huì)有一個(gè)最大值上限辉饱,因此若方法區(qū)(含運(yùn)行時(shí)常量池)占用內(nèi)存到達(dá)其最大值搬男,且無法再申請(qǐng)到內(nèi)存時(shí),便會(huì)拋出OutOfMemoryError彭沼。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缔逛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子姓惑,更是在濱河造成了極大的恐慌褐奴,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件于毙,死亡現(xiàn)場(chǎng)離奇詭異敦冬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)唯沮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門脖旱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人介蛉,你說我怎么就攤上這事夯缺。” “怎么了甘耿?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵踊兜,是天一觀的道長。 經(jīng)常有香客問我佳恬,道長捏境,這世上最難降的妖魔是什么于游? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮垫言,結(jié)果婚禮上贰剥,老公的妹妹穿的比我還像新娘。我一直安慰自己筷频,他們只是感情好蚌成,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凛捏,像睡著了一般担忧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坯癣,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天瓶盛,我揣著相機(jī)與錄音,去河邊找鬼示罗。 笑死惩猫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚜点。 我是一名探鬼主播轧房,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绍绘!你這毒婦竟也來了奶镶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤脯倒,失蹤者是張志新(化名)和其女友劉穎实辑,沒想到半個(gè)月后捺氢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藻丢,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年摄乒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悠反。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡馍佑,死狀恐怖斋否,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拭荤,我是刑警寧澤茵臭,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站舅世,受9級(jí)特大地震影響旦委,放射性物質(zhì)發(fā)生泄漏奇徒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一缨硝、第九天 我趴在偏房一處隱蔽的房頂上張望摩钙。 院中可真熱鬧,春花似錦查辩、人聲如沸胖笛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽长踊。三九已至,卻和暖如春谬返,著一層夾襖步出監(jiān)牢的瞬間之斯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工遣铝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佑刷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓酿炸,卻偏偏與公主長得像瘫絮,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子填硕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350