Java面試題系列(五)——JVM及垃圾回收機制

1. JVM(https://blog.csdn.net/qq_41701956/article/details/81664921)

  • JVM的作用:解釋運行字節(jié)碼程序消除平臺相關(guān)性扼鞋。jvm將java字節(jié)碼解釋為具體平臺的具體指令申鱼。一般的高級語言如要在不同的平臺上運行,至少需要編譯成不同的目標(biāo)代碼云头。而引入JVM后捐友,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平臺相關(guān)的信息溃槐,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標(biāo)代碼(字節(jié)碼)匣砖,就可以在多種平臺上不加修改地運行。Java虛擬機在執(zhí)行字節(jié)碼時昏滴,把字節(jié)碼解釋成具體平臺上的機器指令執(zhí)行猴鲫。

  • JVM常見問題:https://mp.weixin.qq.com/s/Xo3_ZTVruhFSTMSrmJLvrw

  • JVM知識結(jié)構(gòu)圖


    image.png
  • JVM內(nèi)存結(jié)構(gòu)圖


    image.png
  • 程序計數(shù)器:內(nèi)存空間小,線程私有谣殊。字節(jié)碼解釋器工作是就是通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行指令的字節(jié)碼指令拂共,分支、循環(huán)姻几、跳轉(zhuǎn)宜狐、異常處理势告、線程恢復(fù)等基礎(chǔ)功能都需要依賴計數(shù)器完成。唯一一個在 Java 虛擬機規(guī)范中沒有規(guī)定任何 OutOfMemoryError 情況的區(qū)域抚恒。

  • 虛擬機棧:線程私有咱台,生命周期和線程一致。描述的是 Java 方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行時都會床創(chuàng)建一個棧幀(Stack Frame)用于存儲局部變量表俭驮、操作數(shù)棧回溺、動態(tài)鏈接、方法出口等信息混萝。每一個方法從調(diào)用直至執(zhí)行結(jié)束遗遵,就對應(yīng)著一個棧幀從虛擬機棧中入棧到出棧的過程。

  • 本地方法棧:Java 虛擬機棧為虛擬機執(zhí)行 Java 方法(也就是字節(jié)碼)服務(wù)逸嘀,而本地方法棧則為虛擬機使用到的 Native 方法服務(wù)瓮恭。

  • 堆:對于絕大多數(shù)應(yīng)用來說,這塊區(qū)域是 JVM 所管理的內(nèi)存中最大的一塊厘熟。線程共享,主要是存放對象實例和數(shù)組维哈。內(nèi)部會劃分出多個線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer, TLAB)绳姨。可以位于物理上不連續(xù)的空間阔挠,但是邏輯上要連續(xù)飘庄。

  • 方法區(qū):屬于共享內(nèi)存區(qū)域,存儲已被虛擬機加載的類信息购撼、常量跪削、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)迂求。

  • 運行時常量池:屬于方法區(qū)一部分碾盐,用于存放編譯期生成的各種字面量和符號引用。編譯器和運行期(String 的 intern() )都可以將常量放入池中揩局。內(nèi)存有限毫玖,無法申請時拋出 OutOfMemoryError。

  • 直接內(nèi)存:非虛擬機運行時數(shù)據(jù)區(qū)的部分

2. 虛擬機棧結(jié)構(gòu)

image.png

3. Java內(nèi)存模型(JMM)

??Java內(nèi)存模型(簡稱JMM)凌盯,是一種規(guī)范付枫。JMM決定一個線程對共享變量的寫入何時對另一個線程可見。從抽象的角度來看驰怎,JMM定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存(main memory)中阐滩,每個線程都有一個私有的本地內(nèi)存(local memory),本地內(nèi)存中存儲了該線程以讀/寫共享變量的副本县忌。線程對變量的操作只能在各自線程的工作內(nèi)存操作掂榔。
JMM的三大特性:

  • 可見性
  • 原子性
  • 有序性
    本地內(nèi)存是JMM的一個抽象概念继效,并不真實存在。它涵蓋了緩存衅疙,寫緩沖區(qū)莲趣,寄存器以及其他的硬件和編譯器優(yōu)化。其關(guān)系模型圖如下圖所示:


    image.png

4. JVM 調(diào)優(yōu)饱溢,查看 JVM 參數(shù)默認(rèn)值

  • jps -v 可以查看 jvm 進程顯示指定的參數(shù)
  • 使用 -XX:+PrintFlagsFinal 可以看到 JVM 所有參數(shù)的值
  • jinfo 可以實時查看和調(diào)整虛擬機各項參數(shù)
  • jstat -gc 12538 5000即會每5秒一次顯示進程號為12538的java進程的GC情況

5. OOM排查方法

1)先查看應(yīng)用進程號pid:ps -ef | grep 應(yīng)用名
2)查看pid垃圾回收情況:  jstat  -gc  pid  5000(時間間隔)
3)開啟OOM快照: 
  -XX:+HeapDumpOnOutOfMemoryError(開啟堆快照)
  -XX:HeapDumpPath=C:/m.hprof(保存文件到哪個目錄)
4)dump 查看方法棧信息:jstack  -l  pid  >  /home/test/jstack.txt
5)dump 查看JVM內(nèi)存分配以及使用情況:jmap  -heap  pid  >  /home/test/jmapHeap.txt
6)dump jvm二進制的內(nèi)存詳細(xì)使用情況

6. 類加載

  • 類加載器:


    image.png
  • 類加載過程:加載喧伞,驗證,準(zhǔn)備绩郎,解析潘鲫,初始化


    image.png
  • 加載:加載是類加載過程中的一個階段,這個階段會在內(nèi)存中生成一個代表這個類的java.lang.Class對象肋杖,作為方法區(qū)這個類的各種數(shù)據(jù)的入口溉仑。

  • 驗證:確保Class文件的字節(jié)流中包含的信息是否符合當(dāng)前虛擬機的要求,并且不會危害虛擬機自身的安全状植。

  • 準(zhǔn)備:準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量的初始值階段浊竟,即在方法區(qū)中分配這些變量所使用的內(nèi)存空間。

  • 解析:解析階段是指虛擬機將常量池中的符號引用替換為直接引用的過程。

  • 初始化:初始化階段是執(zhí)行類構(gòu)造器<client>方法的過程。到了初始階段箍土,才開始真正執(zhí)行類中定義的Java程序代碼。

  • 雙親委派模型

    • 定義:除了頂層的啟動類加載器外后频,其余的類加載器都應(yīng)有自己的父類加載器,這里類加載器之間的父子關(guān)系一般通過組合(Composition)關(guān)系來實現(xiàn)暖途,而不是通過繼承(Inheritance)的關(guān)系實現(xiàn)卑惜。
    • 工作過程:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載驻售,而是把這個請求委派給父類加載器露久,每一個層次的加載器都是如此,依次遞歸芋浮,因此所有的加載請求最終都應(yīng)該傳送到頂層的啟動類加載器中抱环,只有當(dāng)父加載器反饋自己無法完成此加載請求(它搜索范圍中沒有找到所需類)時,子加載器才會嘗試自己加載纸巷。
    • 優(yōu)點:使用雙親委派模型來組織類加載器之間的關(guān)系镇草,使得Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系。例如類java.lang.Object瘤旨,它存放再rt.jar中梯啤,無論哪個類加載器要加載這個類,最終都是委派給處于模型最頂端的啟動類加載器進行加載存哲,因此Object類在程序的各種類加載器環(huán)境中都是同一個類因宇。
    • 打破雙親委派機制的方法:重寫loadclass()方法
    • 打破雙親委派機制的例子:
      • Tomcat七婴,應(yīng)用的類加載器優(yōu)先自行加載應(yīng)用目錄下的 class,并不是先委派給父加載器察滑,加載不了才委派給父加載器打厘。打破的目的是為了完成應(yīng)用間的類隔離。
      • JDK 9贺辰,Extension ClassLoader 被 Platform ClassLoader 取代户盯,當(dāng)平臺及應(yīng)用程序類加載器收到類加載請求,在委派給父加載器加載前饲化,要先判斷該類是否能夠歸屬到某一個系統(tǒng)模塊中莽鸭,如果可以找到這樣的歸屬關(guān)系,就要優(yōu)先委派給負(fù)責(zé)那個模塊的加載器完成加載吃靠。打破的原因硫眨,是為了添加模塊化的特性。
    • 沙箱安全機制:防止惡意代碼污染java源代碼巢块。

7. JVM加載class文件的原理

??JVM中類的裝載是由ClassLoader和它的子類來實現(xiàn)的礁阁,Java ClassLoader 是一個重要的Java運行時系統(tǒng)組件,它負(fù)責(zé)在運行時查找和裝入類文件的類族奢。
??Java中的所有類氮兵,都需要由類加載器裝載到JVM中才能運行。類加載器本身也是一個類歹鱼,而它的工作就是把class文件從硬盤讀取到內(nèi)存中。在寫程序的時候卜高,我們幾乎不需要關(guān)心類的加載弥姻,因為這些都是隱式裝載的,除非我們有特殊的用法掺涛,像是反射庭敦,就需要顯式的加載所需要的類。
??類裝載方式薪缆,有兩種

  • 隱式裝載秧廉,程序在運行過程中當(dāng)碰到通過new 等方式生成對象時,隱式調(diào)用類裝載器加載對應(yīng)的類到j(luò)vm中
  • 顯式裝載拣帽,通過class.forname()等方法疼电,顯式加載需要的類,隱式加載與顯式加載的區(qū)別:兩者本質(zhì)是一樣的减拭。
    ??Java類的加載是動態(tài)的蔽豺,它并不會一次性將所有類全部加載后再運行,而是保證程序運行的基礎(chǔ)類(像是基類)完全加載到j(luò)vm中拧粪,至于其他類修陡,則在需要的時候才加載沧侥。這當(dāng)然就是為了節(jié)省內(nèi)存開銷。

8. GC Roots

作為GCRoots的對象包括下面幾種:
1)虛擬機棧(棧幀中的局部變量區(qū)魄鸦,也叫做局部變量表)中引用的對象宴杀。
2)方法區(qū)中的類靜態(tài)屬性引用的對象。
3)方法區(qū)中常量引用的對象拾因。
4)本地方法棧中JNI(Native方法)引用的對象旺罢。

9. 對象可達(dá)性分析

  • 如果對象在進行可達(dá)性分析后發(fā)現(xiàn)沒有與GCRoots相連的引用鏈,則該對象被第一次標(biāo)記并進行一次篩選盾致,篩選條件為是否有必要執(zhí)行該對象的finalize方法主经,若對象沒有覆蓋finalize方法或者該finalize方法是否已經(jīng)被虛擬機執(zhí)行過了,則均視作不必要執(zhí)行該對象的finalize方法庭惜,即該對象將會被回收罩驻。反之,若對象覆蓋了finalize方法并且該finalize方法并沒有被執(zhí)行過护赊,那么惠遏,這個對象會被放置在一個叫F-Queue的隊列中,之后會由虛擬機自動建立的骏啰、優(yōu)先級低的Finalizer線程去執(zhí)行节吮,而虛擬機不必要等待該線程執(zhí)行結(jié)束,即虛擬機只負(fù)責(zé)建立線程判耕,其他的事情交給此線程去處理透绩。
  • 對F-Queue中對象進行第二次標(biāo)記,如果對象在finalize方法中拯救了自己壁熄,即關(guān)聯(lián)上了GCRoots引用鏈帚豪,如把this關(guān)鍵字賦值給其他變量,那么在第二次標(biāo)記的時候該對象將從“即將回收”的集合中移除草丧,如果對象還是沒有拯救自己狸臣,那就會被回收。


    image.png

10. 垃圾回收機制

??堆分為新生代和老年代昌执,新生代默認(rèn)占總空間的 1/3烛亦,老年代默認(rèn)占 2/3。新生代使用復(fù)制算法懂拾,有 3 個分區(qū):Eden煤禽、To Survivor、From Survivor岖赋,它們的默認(rèn)占比是 8:1:1呜师。
??當(dāng)新生代中的 Eden 區(qū)內(nèi)存不足時,就會觸發(fā) Minor GC贾节,過程如下:
1)在 Eden 區(qū)執(zhí)行了第一次 GC 之后汁汗,存活的對象會被移動到其中一個 Survivor 分區(qū)衷畦;
2)Eden 區(qū)再次 GC,這時會采用復(fù)制算法知牌,將 Eden 和 from 區(qū)一起清理祈争,存活的對象會被復(fù)制到 to 區(qū);
3)移動一次角寸,對象年齡加 1菩混,對象年齡大于一定閥值會直接移動到老年代
4)Survivor 區(qū)相同年齡所有對象大小的總和 > (Survivor 區(qū)內(nèi)存大小 * 目標(biāo)使用率)時,大于或等于該年齡的對象直接進入老年代扁藕。其中這個使用率通過 -XX:TargetSurvivorRatio 指定沮峡,默認(rèn)為 50%
5)Survivor 區(qū)內(nèi)存不足會發(fā)生擔(dān)保分配
6)年齡超過指定大小的對象可以直接進入老年代
7)Major GC,指的是老年代的垃圾清理亿柑,但并未找到明確說明何時在進行Major GC
8)FullGC邢疙,整個堆的垃圾收集,觸發(fā)條件:

  • 每次晉升到老年代的對象平均大小>老年代剩余空間
  • MinorGC后存活的對象超過了老年代剩余空間
  • 元空間不足
  • System.gc()
  • CMS GC異常望薄,promotion failed:MinorGC時疟游,survivor空間放不下,對象只能放入老年代痕支,而老年代也放不下造成颁虐;concurrent mode failure:GC時,同時有對象要放入老年代卧须,而老年代空間不足造成
  • 堆內(nèi)存分配很大的對象

11. 垃圾回收算法

  • 引用計數(shù)法:給對象中添加一個引用計數(shù)器另绩,每當(dāng)一個地方引用這個對象時,計數(shù)器值+1花嘶;當(dāng)引用失效時板熊,計數(shù)器值-1。任何時刻計數(shù)值為0的對象就是不可能再被使用的察绷。
    • 缺點:(1)每次給對象賦值時都要維護引用計數(shù)器,且計數(shù)器本身也有一定的消耗津辩;(2)較難處理循環(huán)引用
  • 復(fù)制算法:(年輕代)
    • 優(yōu)點:(1)不產(chǎn)生內(nèi)存碎片拆撼;(2)速度快
    • 缺點:浪費10%的內(nèi)存空間
  • 標(biāo)記清除算法(老年代):先標(biāo)記出要回收的對象,然后統(tǒng)一回收這些對象
    • 優(yōu)點:節(jié)省空間
    • 缺點:產(chǎn)生內(nèi)存碎片喘沿;
  • 標(biāo)記整理算法(老年代):先標(biāo)記清除闸度,再次掃描并往一端滑動存活對象。
    • 優(yōu)點:不產(chǎn)生內(nèi)存碎片蚜印;
    • 缺點:需要移動對象的成本莺禁,耗時嚴(yán)重

12. 垃圾收集器

image.png

1)Serial收集器:新生代收集器,使用停止復(fù)制算法窄赋,使用一個線程進行GC哟冬,其它工作線程暫停楼熄。使用-XX:+UseSerialGC可以使用Serial+Serial Old模式運行進行內(nèi)存回收(這也是虛擬機在Client模式下運行的默認(rèn)值)


image.png

2)Serial Old收集器:老年代收集器,單線程收集器浩峡,使用標(biāo)記整理(整理的方法是Sweep(清理)和Compact(壓縮)可岂,清理是將廢棄的對象干掉,只留幸存的對象翰灾,壓縮是將移動對象缕粹,將空間填滿保證內(nèi)存分為2塊,一塊全是對象纸淮,一塊空閑)算法平斩,使用單線程進行GC,其它工作線程暫停(注意咽块,在老年代中進行標(biāo) 記整理算法清理绘面,也需要暫停其它線程),在JDK1.5之前糜芳,Serial Old收集器與ParallelScavenge搭配使用飒货。
3)ParNew收集器:新生代收集器,使用停止復(fù)制算法峭竣,Serial收集器的多線程版塘辅,用多個線程進行GC,其它工作線程暫停皆撩,關(guān)注縮短垃圾收集時間扣墩。使用-XX:+UseParNewGC開關(guān)來控制使用ParNew+Serial Old收集器組合收集內(nèi)存;使用-XX:ParallelGCThreads來設(shè)置執(zhí)行內(nèi)存回收的線程數(shù)扛吞。


image.png

4)Parallel Scavenge 收集器:新生代收集器呻惕,使用停止復(fù)制算法,關(guān)注CPU吞吐量滥比,即運行用戶代碼的時間/總時間亚脆,比如:JVM運行100分鐘,其中運行用戶代碼99分鐘盲泛,垃 圾收集1分鐘濒持,則吞吐量是99%,這種收集器能最高效率的利用CPU寺滚,適合運行后臺運算(關(guān)注縮短垃圾收集時間的收集器柑营,如CMS,等待時間很少村视,所以適 合用戶交互官套,提高用戶體驗)。使用-XX:+UseParallelGC開關(guān)控制使用 Parallel Scavenge+Serial Old收集器組合回收垃圾(這也是在Server模式下的默認(rèn)值);使用-XX:GCTimeRatio來設(shè)置用戶執(zhí)行時間占總時間的比例奶赔,默認(rèn)99惋嚎,即 1%的時間用來進行垃圾回收。使用-XX:MaxGCPauseMillis設(shè)置GC的最大停頓時間(這個參數(shù)只對Parallel Scavenge有效)
5)Parallel Old收集器:老年代收集器纺阔,多線程瘸彤,多線程機制與Parallel Scavenge差不錯,使用標(biāo)記整理(與Serial Old不同笛钝,這里的整理是Summary(匯總)和Compact(壓縮)质况,匯總的意思就是將幸存的對象復(fù)制到預(yù)先準(zhǔn)備好的區(qū)域,而不是像Sweep(清 理)那樣清理廢棄的對象)算法玻靡,在Parallel Old執(zhí)行時结榄,仍然需要暫停其它線程。Parallel Old在多核計算中很有用囤捻。Parallel Old出現(xiàn)后(JDK 1.6)臼朗,與Parallel Scavenge配合有很好的效果,充分體現(xiàn)Parallel Scavenge收集器吞吐量優(yōu)先的效果蝎土。使用-XX:+UseParallelOldGC開關(guān)控制使用Parallel Scavenge +Parallel Old組合收集器進行收集视哑。


image.png

6)CMS(Concurrent Mark Sweep)收集器:老年代收集器,致力于獲取最短回收停頓時間誊涯,使用標(biāo)記清除算法挡毅,多線程,優(yōu)點是并發(fā)收集(用戶線程可以和GC線程同時工作)暴构,停頓小跪呈。使用-XX:+UseConcMarkSweepGC進行ParNew+CMS+Serial Old進行內(nèi)存回收,優(yōu)先使用ParNew+CMS(原因見后面)取逾,當(dāng)用戶線程內(nèi)存不足時耗绿,采用備用方案Serial Old收集。解決內(nèi)存碎片問題:讓CMS在進行一定次數(shù)的Full GC(標(biāo)記清除)的時候進行一次標(biāo)記整理算法砾隅。


image.png
  • 初始標(biāo)記:標(biāo)記GC roots直接關(guān)聯(lián)的對象误阻,速度快
  • 并發(fā)標(biāo)記:GC Roots Tracing過程
  • 重新標(biāo)記:修正并發(fā)標(biāo)記期間用戶進程繼續(xù)運行而產(chǎn)生變化的標(biāo)記,耗時比初始標(biāo)記長晴埂,但遠(yuǎn)小于并發(fā)標(biāo)記
  • 并發(fā)清除:清除標(biāo)記的對象

7)G1(Garbage First)收集器:區(qū)域化垃圾收集器究反,物理上不區(qū)分新生代和老年代。采用標(biāo)記整理的算法邑时,與CMS相比:(1)不會產(chǎn)生內(nèi)存碎片;(2)用戶可以指定垃圾回收時間特姐。G1 收集器晶丘,相關(guān)配置如下:

-Xmx12g
-Xms12g
-XX:+UseG1GC
-XX:InitiatingHeapOccupancyPercent=45
-XX:MaxGCPauseMillis=200
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m
-XX:MaxDirectMemorySize=512m
  • G1將新生代,老年代的物理空間劃分取消了。
  • G1算法將堆劃分為若干個區(qū)域(Region)浅浮,它仍然屬于分代收集器沫浆。不過,這些區(qū)域的一部分包含新生代滚秩,新生代的垃圾收集依然采用暫停所有應(yīng)用線程的方式专执,將存活對象拷貝到老年代或者Survivor空間。老年代也分成很多區(qū)域郁油,G1收集器通過將對象從一個區(qū)域復(fù)制到另外一個區(qū)域本股,完成了清理工作。H區(qū)域可以是連續(xù)的用來分配比較大的對象


    image.png

8)ZGC
ZGC給Hotspot Garbage Collectors增加了兩種新技術(shù):著色指針和讀屏障桐腌。ZGC的標(biāo)記分為三個階段拄显。

  • 第一階段是STW,其中GC roots被標(biāo)記為活對象案站。
  • 第二階段躬审,同時遍歷對象圖并標(biāo)記所有可訪問的對象。在此階段期間蟆盐,讀屏障針使用掩碼測試所有已加載的引用承边,該掩碼確定它們是否已標(biāo)記或尚未標(biāo)記,如果尚未標(biāo)記引用石挂,則將其添加到隊列以進行標(biāo)記博助。
  • 在遍歷完成之后,有一個最終的誊稚,時間很短的的Stop The World階段翔始,這個階段處理一些邊緣情況(我們現(xiàn)在將它忽略),該階段完成之后標(biāo)記階段就完成了里伯。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末城瞎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子疾瓮,更是在濱河造成了極大的恐慌脖镀,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狼电,死亡現(xiàn)場離奇詭異蜒灰,居然都是意外死亡,警方通過查閱死者的電腦和手機肩碟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門强窖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人削祈,你說我怎么就攤上這事翅溺∧月” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵咙崎,是天一觀的道長优幸。 經(jīng)常有香客問我,道長褪猛,這世上最難降的妖魔是什么网杆? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮伊滋,結(jié)果婚禮上碳却,老公的妹妹穿的比我還像新娘。我一直安慰自己新啼,他們只是感情好追城,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著燥撞,像睡著了一般座柱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上物舒,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天色洞,我揣著相機與錄音,去河邊找鬼冠胯。 笑死火诸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的荠察。 我是一名探鬼主播置蜀,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悉盆!你這毒婦竟也來了盯荤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤焕盟,失蹤者是張志新(化名)和其女友劉穎秋秤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脚翘,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡灼卢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了来农。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞋真。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖沃于,靈堂內(nèi)的尸體忽然破棺而出涩咖,到底是詐尸還是另有隱情赶袄,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布抠藕,位于F島的核電站,受9級特大地震影響蒋困,放射性物質(zhì)發(fā)生泄漏盾似。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一雪标、第九天 我趴在偏房一處隱蔽的房頂上張望零院。 院中可真熱鬧,春花似錦村刨、人聲如沸告抄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽打洼。三九已至,卻和暖如春逆粹,著一層夾襖步出監(jiān)牢的瞬間募疮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工僻弹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阿浓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓蹋绽,卻偏偏與公主長得像芭毙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子卸耘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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