Java 虛擬機(jī)簡介

###(未完成)###

????Java的運(yùn)行原理雖然在我們開發(fā)人員中觉渴,不一定會(huì)進(jìn)行干涉检痰。但是了解其運(yùn)行原理愤惰,則能更高效地避免或定位到相對(duì)應(yīng)的Bug苇经。本文主要通過以下幾個(gè)方面進(jìn)行闡述:

????1、Java虛擬機(jī)的數(shù)據(jù)區(qū)域組成與簡介

????2宦言、對(duì)象的創(chuàng)建與查找

????3扇单、垃圾回收機(jī)制(GC)與內(nèi)存分配管理

????4、線程與內(nèi)存模型

????希望借由這幾個(gè)方面能夠有比較詳細(xì)的闡述蜡励,使得更好地理解Java虛擬機(jī)的運(yùn)行機(jī)制令花。

1阻桅、Java虛擬機(jī)的數(shù)據(jù)區(qū)域組成與簡介

????我們知道每一個(gè)Java應(yīng)用運(yùn)行后凉倚,系統(tǒng)都會(huì)創(chuàng)建一個(gè)Java虛擬機(jī)對(duì)整個(gè)程序進(jìn)行運(yùn)轉(zhuǎn),每個(gè)Java的虛擬機(jī)運(yùn)行時(shí)嫂沉,主要分成5個(gè)數(shù)據(jù)區(qū):PC(程序計(jì)數(shù)器)稽寒、虛擬機(jī)棧(VM Stack)、本地方法區(qū)棧(Native Method Stack)趟章、堆(Heap)杏糙、方法區(qū)(Method Area)慎王。從眾所周知,每個(gè)應(yīng)用內(nèi)很可能會(huì)存在多個(gè)線程宏侍,而這5個(gè)數(shù)據(jù)區(qū)赖淤,前三者是線程所獨(dú)有的(即每個(gè)線程都會(huì)各自擁有,不進(jìn)行線程間共享)谅河。但是后兩者(堆咱旱、方法區(qū))則是線程間共有的。我們看下圖:

JVM數(shù)據(jù)區(qū)域簡圖—圖1
JVM數(shù)據(jù)區(qū)域簡圖—圖2

? ? 從上圖圖1我們可知虛擬機(jī)的數(shù)據(jù)區(qū)及其各自負(fù)責(zé)的一些數(shù)據(jù)劝赔,圖二則更能生動(dòng)地展示多線程情況下诡右,數(shù)據(jù)區(qū)各自的位置與獨(dú)立性熬尺。在這里,我們簡單地解釋一下各個(gè)數(shù)據(jù)區(qū)的責(zé)任作用:

? ? 1诸典、PC(程序計(jì)數(shù)器)

? ? 一塊很小的內(nèi)存空間,存儲(chǔ)了下一條需要執(zhí)行的字節(jié)碼指令地址崎苗。比如分支狐粱、跳轉(zhuǎn)、循環(huán)等都需要依賴其計(jì)數(shù)器才能完成胆数。它是屬于線程私有的脑奠,但是多線程并發(fā)的實(shí)現(xiàn)是通過線程輪換并分配執(zhí)行時(shí)間完成的,所以在JVM中幅慌,某一時(shí)間內(nèi)是只有一條指令在執(zhí)行的宋欺。而它也是唯一一個(gè)在Java規(guī)范中,OutOfMememory未曾定義發(fā)生的區(qū)域(即不會(huì)在該區(qū)域發(fā)生OutOfMememory異常)胰伍。

? ? 2齿诞、虛擬機(jī)棧(VM Stack)

? ? 這個(gè)數(shù)據(jù)區(qū)主要對(duì)應(yīng)了Java對(duì)象方法,主要存儲(chǔ)方法的信息骂租,局部變量祷杈,方法出口等。它是由一個(gè)個(gè)棧幀所組成的渗饮,在每次調(diào)用Java方法的時(shí)候創(chuàng)建一個(gè)棧幀但汞,然后放入虛擬機(jī)棧中,采取的是后入先出(LIFO)的方式互站,即最新調(diào)用的方法優(yōu)先執(zhí)行私蕾。它是屬于線程所私有,整個(gè)虛擬機(jī)棧作用也造成其生命周期跟線程的生命周期是相同的胡桃。 (ps:這里的局部變量表中存儲(chǔ)局部變量值(基本數(shù)據(jù)類型)踩叭,局部變量(實(shí)例對(duì)象)引用。)? ?

? ? 由于后進(jìn)先出的機(jī)制,虛擬機(jī)棧頂端的棧(被稱作當(dāng)前活動(dòng)棧幀)容贝,是該虛擬機(jī)棧中唯一活躍(執(zhí)行)的棧幀自脯。由此我們可以知道,一個(gè)棧幀從入棧到出棧斤富,對(duì)應(yīng)的是一個(gè)方法的整個(gè)過程膏潮,其記錄的信息自然也是整個(gè)方法所需要和產(chǎn)生的信息。具體有:

棧幀構(gòu)成講解圖

? ? 這里說一下棧幀里的局部變量表满力,它包含的主要是:編譯期間就知道的8種基本數(shù)據(jù)類型戏罢、對(duì)象引用和 returnAddress 類型(指向了一條字節(jié)碼指令的地址)

????3、本地方法棧

? ? 又稱本地方法區(qū)脚囊,跟虛擬機(jī)棧的區(qū)別在于:虛擬機(jī)棧服務(wù)于Java對(duì)象方法龟糕,而本地方法棧則服務(wù)于本地方法(Native)。

????也因此無論是虛擬機(jī)棧悔耘,或者本地方法區(qū)都存在這兩種異常的可能:

? ? (1)StackOverflowError:線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度讲岁;

? ? (2)OutOfMemoryError:如果虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展衬以,而擴(kuò)展時(shí)無法申請(qǐng)到足夠的內(nèi)存缓艳。

? ? 4、堆(Heap)

? ? 幾乎所有的對(duì)象實(shí)例(需要new出來的看峻,基本數(shù)據(jù)類型除外的所有對(duì)象類型)阶淘、數(shù)組內(nèi)容存放區(qū)域。因其變化性互妓,對(duì)于一般情況溪窒,對(duì)堆所分配的內(nèi)存是整個(gè)虛擬機(jī)的數(shù)據(jù)區(qū)中最大的一塊。也因此是垃圾回收(GC)主要運(yùn)作區(qū)域冯勉,OOM最容易發(fā)生的區(qū)域澈蚌。

? ? 我們知道,堆是所有線程所共享的灼狰,也因此內(nèi)部會(huì)對(duì)線程分配出私有的數(shù)據(jù)緩沖區(qū)(TLAB)宛瞄。對(duì)于每個(gè)數(shù)據(jù)緩沖區(qū)來說,它所分配的內(nèi)存區(qū)域不一定在物理?xiàng)l件上是完整的一塊內(nèi)存區(qū)域交胚,只要在邏輯上是完整的一塊區(qū)域即可份汗。

? ? 5、方法區(qū)(Method Area)

? ??屬于線程共享內(nèi)存區(qū)域蝴簇,存儲(chǔ)已被虛擬機(jī)加載的類信息杯活、常量、靜態(tài)變量军熏、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)轩猩。其組成為:

方法區(qū)組成表

2卷扮、對(duì)象的創(chuàng)建與查找

? ? 在這一塊主要了解一下荡澎,整個(gè)數(shù)據(jù)的創(chuàng)建于管理流程均践,對(duì)于后面的垃圾回收、內(nèi)存相關(guān)的問題打一下基礎(chǔ)摩幔。對(duì)象的創(chuàng)建彤委,最常見的就是通過new指令來獲取。創(chuàng)建對(duì)象的流程或衡,大致上分為兩個(gè)部分:初始化焦影、實(shí)例化。

對(duì)象初始化流程圖

? ? 到此封断,初始化已經(jīng)完成斯辰,接下來就是實(shí)例化了。實(shí)例化其實(shí)也有幾個(gè)階段:申請(qǐng)內(nèi)存來存儲(chǔ)成員變量坡疼,在申請(qǐng)成功之前彬呻,這些成員變量的值為默認(rèn)零值。等到內(nèi)存申請(qǐng)成功了柄瑰,才將代碼中設(shè)置的初始值賦加過去闸氮。實(shí)例化后獲得一個(gè)對(duì)象實(shí)例,而對(duì)象實(shí)例主要有:對(duì)象頭(Header)教沾、實(shí)例數(shù)據(jù)(Instance Data)和對(duì)齊填充(Padding)蒲跨。????

? ? (1)對(duì)象頭:包括了對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù)(GC年代標(biāo)記、哈希碼授翻、鎖狀態(tài)標(biāo)記等)+類型指針(對(duì)象所屬的哪個(gè)類)

? ? (2)實(shí)例數(shù)據(jù):代碼中各字段內(nèi)容

? ? (3)對(duì)齊填充:不是必然需要或悲,主要是占位,保證對(duì)象大小是某個(gè)字節(jié)的整數(shù)倍堪唐。

? ? 對(duì)象的內(nèi)容存儲(chǔ)是毋庸置疑的隆箩,但外部持有的引用指向的有兩種可能:1、對(duì)象的實(shí)例內(nèi)容羔杨;2捌臊、對(duì)象的句柄(其實(shí)就是一個(gè)指向?qū)嵗齼?nèi)容的引用,比1類多了一層句柄而已)兜材。前者優(yōu)點(diǎn)是訪問速度快理澎,后者的優(yōu)點(diǎn)是當(dāng)對(duì)象需要頻繁GC的時(shí)候?qū)?nèi)存比較友好。

3曙寡、垃圾回收機(jī)制(GC)與內(nèi)存分配管理

? ? 從第一節(jié)數(shù)據(jù)區(qū)域的劃分我們可以知道糠爬,PC、虛擬機(jī)棧举庶、本地方法棧會(huì)隨著線程的結(jié)束而回收执隧,但是屬于線程共有的堆和方法區(qū)則一直存在著,為了解放開發(fā)人員手動(dòng)回收內(nèi)存操作的負(fù)累,這也就造成了內(nèi)部需要在運(yùn)行時(shí)對(duì)不需要再繼續(xù)存在的變量——垃圾進(jìn)行回收镀琉。而垃圾回收最主要的難點(diǎn)就是峦嗤,怎么分辨哪些對(duì)象是有用,而哪些對(duì)象是垃圾需要進(jìn)行回收屋摔。因此提出了幾種算法烁设。在這之前,我們先對(duì)引用類別進(jìn)行了解一下钓试。

? ?3.1 引用的類型

????a装黑、強(qiáng)引用:通常是new指令所返回,如果一個(gè)對(duì)象的強(qiáng)引用存在弓熏,就不會(huì)被GC所回收恋谭;

????b、軟引用:SoftReference挽鞠,平時(shí)不會(huì)對(duì)存在軟引用的對(duì)象進(jìn)行回收箕别,但是當(dāng)內(nèi)存不足的時(shí)候(內(nèi)存溢出),則會(huì)將只存在軟引用的對(duì)象列入回收范圍內(nèi)滞谢;

????c串稀、弱引用:WeakReference,每次GC的時(shí)候都會(huì)對(duì)弱引用進(jìn)行回收狮杨,也因此每次弱引用的存活時(shí)間都是每次GC之間母截;

????d、虛引用:PhantomReference ,無法通過虛引用獲取一個(gè)對(duì)象的實(shí)例橄教,為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知清寇。

? ?3.2 判斷對(duì)象存活的算法

? ? a、引用計(jì)數(shù)法

? ??給對(duì)象添加一個(gè)引用計(jì)數(shù)器护蝶。但是難以解決循環(huán)引用問題华烟。

循環(huán)引用問題截圖

? ? b、可達(dá)性算法

? ? 以'GC Roots'作為起點(diǎn)持灰,將對(duì)象的引用陸續(xù)加入形成一顆樹(如obj1與GC Roots相連盔夜,obj2與obj1相連)。當(dāng)能夠通過GC Roots到達(dá)某個(gè)節(jié)點(diǎn)堤魁,則該對(duì)象仍舊有用喂链,否則視為垃圾。而可作為GC Roots的對(duì)象有這幾種:虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象妥泉、方法區(qū)中類靜態(tài)屬性引用的對(duì)象椭微、方法區(qū)中常量引用的對(duì)象、本地方法棧中 JNI(即一般說的 Native 方法) 引用的對(duì)象盲链。

? ? 在可達(dá)性算法中蝇率,要把對(duì)象進(jìn)行回收其實(shí)經(jīng)過兩次檢查:首先將不可達(dá)的對(duì)象放入回收考慮范圍(標(biāo)記起來)迟杂,之后再回收考慮范圍的對(duì)象(被標(biāo)記的對(duì)象)再進(jìn)行finalize()的檢查:沒有覆蓋finalize()方法,或者finalize() 方法已經(jīng)被虛擬機(jī)調(diào)用過本慕。將打上需要回收的標(biāo)志排拷。當(dāng)然,每個(gè)對(duì)象的finalize()只會(huì)被系統(tǒng)調(diào)用一次间狂,也就是說對(duì)象能夠在finalize()方法中最后“拯救自己”一次攻泼,但也僅僅只有一次火架。

????3.3 對(duì)象回收的算法

? ? a鉴象、標(biāo)記清除法:這個(gè)就是字面意思,將需要回收的對(duì)象進(jìn)行標(biāo)記何鸡,然后將標(biāo)記的對(duì)象直接回收清除就行了纺弊。優(yōu)點(diǎn)是簡單,缺點(diǎn)就是效率不高骡男,而且會(huì)造成內(nèi)存碎片較多(內(nèi)存碎片過多則可能會(huì)在下一次需要一個(gè)較大內(nèi)存的對(duì)象因無法找到一個(gè)連續(xù)的內(nèi)存觸發(fā)新一次的GC)淆游;

? ? b、復(fù)制算法:將內(nèi)存分成兩塊區(qū)域隔盛,每次只GC其中一塊犹菱,然后將存活的對(duì)象復(fù)制到另一塊上面去,輪流使用吮炕。由于每次GC一般都能回收大量的對(duì)象腊脱,也因此提出了比較優(yōu)化的方案:將內(nèi)存分成兩種類型(Eden 、Survivor)龙亲,3塊區(qū)域(Eden :Survivor:Survivor=8:1:1)陕凹,由此每一次運(yùn)行時(shí)候?qū)⒖臻e出一塊Survivor區(qū)域(約是所占內(nèi)存區(qū)域的10%)備用。

????我們假設(shè)名稱為E塊鳄炉、S1塊杜耙,S2塊,此次當(dāng)GC的時(shí)候?qū)⒋婊畹膶?duì)象放到E塊和S1塊拂盯,S2塊備用佑女。當(dāng)GC對(duì)E塊和S1塊進(jìn)行清理回收的時(shí)候,將存活的對(duì)象復(fù)制放入S2塊谈竿。這樣E塊和S1塊空出來了珊豹,這時(shí)候?qū)塊和S2塊用于這次的運(yùn)行產(chǎn)生的對(duì)象存儲(chǔ),S1塊作為備用(Survivor依次備用)榕订。

? ? 優(yōu)點(diǎn):高效店茶、實(shí)現(xiàn)也算簡單,也不會(huì)產(chǎn)生內(nèi)存碎片劫恒,適合生命周期比較短的(如新生代類)對(duì)象進(jìn)行管理贩幻;

? ? 缺點(diǎn):除了增加復(fù)制的時(shí)間花銷之外轿腺,還有就是必須浪費(fèi)一部分內(nèi)存(最初是要浪費(fèi)一半的內(nèi)存空間,即使是優(yōu)化后也需要浪費(fèi)10%的內(nèi)存空間)丛楚。如果每次存活的對(duì)象(老年代類的對(duì)象)較多的時(shí)候族壳,就加大了不小的負(fù)擔(dān)。在優(yōu)化方案中趣些,當(dāng)存活的對(duì)象超過10%的時(shí)候仿荆,仍舊需要通過分代算法進(jìn)行補(bǔ)足(依賴于老生代進(jìn)行分配擔(dān)保,所以大對(duì)象直接進(jìn)入老年代)坏平。

? ? c拢操、標(biāo)記整理法:對(duì)存活的對(duì)象進(jìn)行標(biāo)記,然后移動(dòng)到內(nèi)存的一端舶替,之后再對(duì)剩余的內(nèi)存空間進(jìn)行清理令境。優(yōu)點(diǎn)就是每次都能夠整理出比較連續(xù)完整的內(nèi)存空間,缺點(diǎn)就是需要增加存活對(duì)象移動(dòng)的成本顾瞪。

?????3.4 內(nèi)存分配與回收策略

????由于對(duì)象的生命周期可能存在較大差距舔庶,一刀切地采用某種算法弊端就十分明顯。因此引入歸類的方法陈醒,將對(duì)象分代進(jìn)行管理惕橙,在不同代類的對(duì)象管理方法各自采用不同的算法,其中分成:新生代(年輕代)钉跷、老生代(老年代)弥鹦、永生代。

? ? (1)新生代:該內(nèi)存區(qū)域主要用于存放新創(chuàng)建的對(duì)象尘应,該區(qū)域的內(nèi)存容量相對(duì)會(huì)較惶凝,垃圾回收也比較頻繁。采用的算法為復(fù)制算法(8:1:1優(yōu)化版)犬钢。

? ? (2)老生代:該內(nèi)存區(qū)域主要存放JVM中生命周期較長的對(duì)象(經(jīng)過幾次的Young Gen的垃圾回收后仍然存在)苍鲜,該區(qū)域內(nèi)存相對(duì)較大,垃圾回收相對(duì)不頻繁玷犹,采用的是標(biāo)記整理法混滔。由于老生代的回收速度會(huì)比較慢,所以要盡量避免老生代的垃圾回收歹颓。

? ? (3)永生代:該內(nèi)存區(qū)域主要存放類定義坯屿、字節(jié)碼和常量等很少會(huì)變更(或者說不會(huì)變更)的信息。該內(nèi)存區(qū)域是由JVM在運(yùn)行時(shí)根據(jù)應(yīng)用程序使用的類來填充的巍扛。此外领跛,Java SE類庫和方法也存儲(chǔ)在這里。如果JVM發(fā)現(xiàn)某些類不再需要撤奸,并且其他類可能需要空間吠昭,則這些類可能會(huì)被回收喊括。

? ? 在新生代中,如果存活的對(duì)象總量超過了內(nèi)存的10%矢棚,需要老生代進(jìn)行分擔(dān)即:該情況下會(huì)對(duì)對(duì)象的年齡進(jìn)行判斷郑什,根據(jù)年齡閾值將超過年齡的對(duì)象轉(zhuǎn)移到老生代中。也因此老生代中的對(duì)象年齡不一定都是相同的蒲肋,甚至一些挺“年輕的”對(duì)象也可能直接進(jìn)入老生代——占據(jù)(或者說需要)大內(nèi)存的對(duì)象蘑拯。

????這里我們將內(nèi)存分配與回收策略統(tǒng)計(jì)一下:

垃圾回收算法優(yōu)缺點(diǎn)及和內(nèi)存適用關(guān)系

4、線程與內(nèi)存模型

? ? 線程與進(jìn)程的定義就不多說了兜粘,這里看看線程并發(fā)的安全必須依賴于以下幾個(gè)方面:

????(1)原子性:提供了一種互斥訪問申窘,同一時(shí)刻只能有一個(gè)線程對(duì)它進(jìn)行操作;

? ? (2)可見性:一個(gè)線程對(duì)主內(nèi)存對(duì)修改可以及時(shí)的被其他線程觀察到妹沙;

? ? (3)一致性:一個(gè)線程觀察其他線程的指令行執(zhí)行順序偶洋,由于指令重新排序的存在熟吏,該觀察結(jié)果一般雜亂無序距糖;

? ? 這里補(bǔ)充一個(gè)概念——指令重排:處理器為了提高程序運(yùn)行效率,可能會(huì)對(duì)輸入代碼進(jìn)行優(yōu)化牵寺。所以在保證程序執(zhí)行結(jié)果+代碼順序執(zhí)行結(jié)果一致的前提下悍引,處理器并不保證每一句代碼執(zhí)行順序都會(huì)按照代碼中的順序來。比如int a=0; int b=1; a++帽氓;b=a+5;(將上述代碼視為4行)中趣斤,第1、2句代碼誰先執(zhí)行并無任何影響黎休,所以在處理器的時(shí)候可能會(huì)先執(zhí)行第2句再執(zhí)行第一句浓领。所以指令重排可能會(huì)打亂代碼的執(zhí)行順序,只要這個(gè)執(zhí)行順序不用想程序或者代碼順序的執(zhí)行結(jié)果势腮。?


線程联贩、工作內(nèi)存、主內(nèi)存的三者交互關(guān)系

? ? 上面就是線程捎拯、工作內(nèi)存與主內(nèi)存的基本交互泪幌,至于工作內(nèi)存與主內(nèi)存的操作包括lock/unlock、read署照、load祸泪、user、store建芙、write等操作没隘,具體的操作對(duì)象與目的就不多說了。這里補(bǔ)充一個(gè)線程并發(fā)的原則——happen - before(先行發(fā)生原則)禁荸,它可以理解為:1右蒲、如果A先行發(fā)生于B微王,則A造成的事件影響(如修改了共享變量、調(diào)用方法等)對(duì)B是可見的品嚣;2炕倘、即使A、B存在happen - before關(guān)系翰撑,在保證執(zhí)行結(jié)果或者代碼順序結(jié)果的前提下罩旋,不保證執(zhí)行順序(也就是說不一定一定要按照Happens-Before原則制定的順序來執(zhí)行,比如指令重排)

? ? 4.1?volatile 關(guān)鍵字

? ? 保證可見性不保證原子性

? ? 4.2?synchronized 關(guān)鍵字

????同步塊大家都比較熟悉眶诈,通過 synchronized 關(guān)鍵字來實(shí)現(xiàn)涨醋,所有加上synchronized 和 塊語句,在多線程訪問的時(shí)候逝撬,同一時(shí)刻只能有一個(gè)線程能夠用浴骂,屬于重量級(jí)的線程安全機(jī)制。synchronized 修飾的方法 或者 代碼塊宪潮。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溯警,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子狡相,更是在濱河造成了極大的恐慌梯轻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尽棕,死亡現(xiàn)場(chǎng)離奇詭異喳挑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滔悉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門伊诵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人回官,你說我怎么就攤上這事曹宴。” “怎么了孙乖?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵浙炼,是天一觀的道長。 經(jīng)常有香客問我唯袄,道長弯屈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任恋拷,我火速辦了婚禮资厉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔬顾。我一直安慰自己宴偿,他們只是感情好湘捎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布窥妇。 她就那樣靜靜地躺著娩践,像睡著了一般翻伺。 火紅的嫁衣襯著肌膚如雪拉宗。 梳的紋絲不亂的頭發(fā)上旦事,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天歪赢,我揣著相機(jī)與錄音,去河邊找鬼。 笑死白对,一個(gè)胖子當(dāng)著我的面吹牛甩恼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播条摸,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钉蒲,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼顷啼!你這毒婦竟也來了昌屉?” 一聲冷哼從身側(cè)響起间驮,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蜻牢,失蹤者是張志新(化名)和其女友劉穎抢呆,沒想到半個(gè)月后抱虐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恳邀,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谣沸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年乳附,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伴澄。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖非凌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敞嗡,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布喉悴,位于F島的核電站棱貌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏粥惧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一涡贱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸锋叨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偷卧。三九已至豺瘤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間听诸,已是汗流浹背坐求。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晌梨,地道東北人桥嗤。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像派任,于是被迫代替她去往敵國和親砸逊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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