JVM垃圾收集器

如果說收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)粉私。

Java虛擬機(jī)規(guī)范中對(duì)垃圾收集器應(yīng)該如何實(shí)現(xiàn)并沒有任何規(guī)定顽腾,因此不同的廠商、版本的虛擬機(jī)所提供的垃圾收集器都可能會(huì)有很大差別,并且一般都會(huì)提供參數(shù)供用戶根據(jù)自己的應(yīng)用特點(diǎn)和要求組合出各個(gè)年代所使用的收集器抄肖。

接下來討論的收集器基于JDK1.7 Update 14 之后的HotSpot虛擬機(jī)(在此版本中正式提供了商用的G1收集器久信,之前G1仍處于實(shí)驗(yàn)狀態(tài)),該虛擬機(jī)包含的所有收集器如下圖所示:

image.png

上圖展示了7種作用于不同分代的收集器漓摩,如果兩個(gè)收集器之間存在連線裙士,就說明它們可以搭配使用。

虛擬機(jī)所處的區(qū)域管毙,則表示它是屬于新生代收集器還是老年代收集器腿椎。Hotspot實(shí)現(xiàn)了如此多的收集器,正是因?yàn)槟壳安o完美的收集器出現(xiàn)夭咬,只是選擇對(duì)具體應(yīng)用最適合的收集器啃炸。

相關(guān)概念

并行和并發(fā)

  • 并行(Parallel):指多條垃圾收集線程并行工作,但此時(shí)用戶線程仍然處于等待狀態(tài)卓舵。
  • 并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時(shí)執(zhí)行(但不一定是并行的南用,可能會(huì)交替執(zhí)行),用戶程序在繼續(xù)運(yùn)行边器。而垃圾收集程序運(yùn)行在另一個(gè)CPU上训枢。

吞吐量(Throughput)

吞吐量就是CPU用于運(yùn)行用戶代碼的時(shí)間與CPU總消耗時(shí)間的比值,即

吞吐量 = 運(yùn)行用戶代碼時(shí)間 /(運(yùn)行用戶代碼時(shí)間 + 垃圾收集時(shí)間)忘巧。

假設(shè)虛擬機(jī)總共運(yùn)行了100分鐘恒界,其中垃圾收集花掉1分鐘,那吞吐量就是99%砚嘴。

Minor GC 和 Full GC

  • 新生代GC(Minor GC):指發(fā)生在新生代的垃圾收集動(dòng)作十酣,因?yàn)镴ava對(duì)象大多都具備朝生夕滅的特性,所以Minor GC非常頻繁际长,一般回收速度也比較快耸采。具體原理見上一篇文章。
  • 老年代GC(Major GC / Full GC):指發(fā)生在老年代的GC工育,出現(xiàn)了Major GC虾宇,經(jīng)常會(huì)伴隨至少一次的Minor GC(但非絕對(duì)的,在Parallel Scavenge收集器的收集策略里就有直接進(jìn)行Major GC的策略選擇過程)如绸。Major GC的速度一般會(huì)比Minor GC慢10倍以上嘱朽。

新生代收集器

Serial收集器

Serial(串行)收集器是最基本、發(fā)展歷史最悠久的收集器怔接,它是采用復(fù)制算法的新生代收集器搪泳,曾經(jīng)(JDK 1.3.1之前)是虛擬機(jī)新生代收集的唯一選擇。

它是一個(gè)單線程收集器扼脐,只會(huì)使用一個(gè)CPU或一條收集線程去完成垃圾收集工作岸军,更重要的是它在進(jìn)行垃圾收集時(shí),必須暫停其他所有的工作線程,直至Serial收集器收集結(jié)束為止(“Stop The World”)艰赞。

這項(xiàng)工作是由虛擬機(jī)在后臺(tái)自動(dòng)發(fā)起和自動(dòng)完成的佣谐,在用戶不可見的情況下把用戶正常工作的線程全部停掉,這對(duì)很多應(yīng)用來說是難以接收的方妖。圖解 Java 垃圾回收機(jī)制台谍,這篇推薦看下。

下圖展示了Serial 收集器(老年代采用Serial Old收集器)的運(yùn)行過程:

image.png

為了消除或減少工作線程因內(nèi)存回收而導(dǎo)致的停頓吁断,HotSpot虛擬機(jī)開發(fā)團(tuán)隊(duì)在JDK 1.3之后的Java發(fā)展歷程中研發(fā)出了各種其他的優(yōu)秀收集器,這些將在稍后介紹坞生。但是這些收集器的誕生并不意味著Serial收集器已經(jīng)“老而無用”仔役,實(shí)際上到現(xiàn)在為止,它依然是HotSpot虛擬機(jī)運(yùn)行在Client模式下的默認(rèn)的新生代收集器是己。

它也有著優(yōu)于其他收集器的地方:簡單而高效(與其他收集器的單線程相比)又兵,對(duì)于限定單個(gè)CPU的環(huán)境來說,Serial收集器由于沒有線程交互的開銷卒废,專心做垃圾收集自然可以獲得更高的單線程收集效率沛厨。

在用戶的桌面應(yīng)用場(chǎng)景中,分配給虛擬機(jī)管理的內(nèi)存一般不會(huì)很大摔认,收集幾十兆甚至一兩百兆的新生代(僅僅是新生代使用的內(nèi)存逆皮,桌面應(yīng)用基本不會(huì)再大了),停頓時(shí)間完全可以控制在幾十毫秒最多一百毫秒以內(nèi)参袱,只要不頻繁發(fā)生电谣,這點(diǎn)停頓時(shí)間可以接收。

所以抹蚀,Serial收集器對(duì)于運(yùn)行在Client模式下的虛擬機(jī)來說是一個(gè)很好的選擇剿牺。

ParNew 收集器

ParNew收集器就是Serial收集器的多線程版本,它也是一個(gè)新生代收集器环壤。除了使用多線程進(jìn)行垃圾收集外晒来,其余行為包括Serial收集器可用的所有控制參數(shù)、收集算法(復(fù)制算法)郑现、Stop The World湃崩、對(duì)象分配規(guī)則、回收策略等與Serial收集器完全相同懂酱,兩者共用了相當(dāng)多的代碼竹习。

ParNew收集器的工作過程如下圖(老年代采用Serial Old收集器):

image.png

ParNew收集器除了使用多線程收集外,其他與Serial收集器相比并無太多創(chuàng)新之處列牺,但它卻是許多運(yùn)行在Server模式下的虛擬機(jī)中首選的新生代收集器整陌,其中有一個(gè)與性能無關(guān)的重要原因是,除了Serial收集器外,目前只有它能和CMS收集器(Concurrent Mark Sweep)配合工作泌辫,CMS收集器是JDK 1.5推出的一個(gè)具有劃時(shí)代意義的收集器随夸,具體內(nèi)容將在稍后進(jìn)行介紹。

ParNew 收集器在單CPU的環(huán)境中絕對(duì)不會(huì)有比Serial收集器有更好的效果震放,甚至由于存在線程交互的開銷宾毒,該收集器在通過超線程技術(shù)實(shí)現(xiàn)的兩個(gè)CPU的環(huán)境中都不能百分之百地保證可以超越。

在多CPU環(huán)境下殿遂,隨著CPU的數(shù)量增加诈铛,它對(duì)于GC時(shí)系統(tǒng)資源的有效利用是很有好處的。它默認(rèn)開啟的收集線程數(shù)與CPU的數(shù)量相同墨礁,在CPU非常多的情況下可使用-XX:ParallerGCThreads參數(shù)設(shè)置幢竹。

Parallel Scavenge 收集器

Parallel Scavenge收集器也是一個(gè)并行的多線程新生代收集器,它也使用復(fù)制算法恩静。Parallel Scavenge收集器的特點(diǎn)是它的關(guān)注點(diǎn)與其他收集器不同焕毫,CMS等收集器的關(guān)注點(diǎn)是盡可能縮短垃圾收集時(shí)用戶線程的停頓時(shí)間,而Parallel Scavenge收集器的目標(biāo)是達(dá)到一個(gè)可控制的吞吐量(Throughput)驶乾。

停頓時(shí)間越短就越適合需要與用戶交互的程序邑飒,良好的響應(yīng)速度能提升用戶體驗(yàn)。而高吞吐量則可以高效率地利用CPU時(shí)間级乐,盡快完成程序的運(yùn)算任務(wù)疙咸,主要適合在后臺(tái)運(yùn)算而不需要太多交互的任務(wù)。

Parallel Scavenge收集器除了會(huì)顯而易見地提供可以精確控制吞吐量的參數(shù)风科,還提供了一個(gè)參數(shù)-XX:+UseAdaptiveSizePolicy罕扎,這是一個(gè)開關(guān)參數(shù),打開參數(shù)后丐重,就不需要手工指定新生代的大星徽佟(-Xmn)、Eden和Survivor區(qū)的比例(-XX:SurvivorRatio)扮惦、晉升老年代對(duì)象年齡(-XX:PretenureSizeThreshold)等細(xì)節(jié)參數(shù)了臀蛛。

虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整這些參數(shù)以提供最合適的停頓時(shí)間或者最大的吞吐量崖蜜,這種方式稱為GC自適應(yīng)的調(diào)節(jié)策略(GC Ergonomics)浊仆。自適應(yīng)調(diào)節(jié)策略也是Parallel Scavenge收集器與ParNew收集器的一個(gè)重要區(qū)別。

另外值得注意的一點(diǎn)是豫领,Parallel Scavenge收集器無法與CMS收集器配合使用抡柿,所以在JDK 1.6推出Parallel Old之前,如果新生代選擇Parallel Scavenge收集器等恐,老年代只有Serial Old收集器能與之配合使用洲劣。

老年代收集器

Serial Old收集器

Serial Old 是 Serial收集器的老年代版本备蚓,它同樣是一個(gè)單線程收集器,使用“標(biāo)記-整理”(Mark-Compact)算法囱稽。

此收集器的主要意義也是在于給Client模式下的虛擬機(jī)使用郊尝。如果在Server模式下,它還有兩大用途:

  • 在JDK1.5 以及之前版本(Parallel Old誕生以前)中與Parallel Scavenge收集器搭配使用战惊。
  • 作為CMS收集器的后備預(yù)案流昏,在并發(fā)收集發(fā)生Concurrent Mode Failure時(shí)使用。

它的工作流程與Serial收集器相同吞获,這里再次給出Serial/Serial Old配合使用的工作流程圖:

image.png

Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本况凉,使用多線程和“標(biāo)記-整理”算法。前面已經(jīng)提到過各拷,這個(gè)收集器是在JDK 1.6中才開始提供的茎刚,在此之前,如果新生代選擇了Parallel Scavenge收集器撤逢。

老年代除了Serial Old以外別無選擇,所以在Parallel Old誕生以后粮坞,“吞吐量優(yōu)先”收集器終于有了比較名副其實(shí)的應(yīng)用組合蚊荣,在注重吞吐量以及CPU資源敏感的場(chǎng)合,都可以優(yōu)先考慮Parallel Scavenge加Parallel Old收集器莫杈。

Parallel Old收集器的工作流程與Parallel Scavenge相同互例,這里給出Parallel Scavenge/Parallel Old收集器配合使用的流程圖:

image.png

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,它非常符合那些集中在互聯(lián)網(wǎng)站或者B/S系統(tǒng)的服務(wù)端上的Java應(yīng)用筝闹,這些應(yīng)用都非常重視服務(wù)的響應(yīng)速度媳叨。從名字上(“Mark Sweep”)就可以看出它是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的。

CMS收集器工作的整個(gè)流程分為以下4個(gè)步驟:

  • 初始標(biāo)記(CMS initial mark):僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象关顷,速度很快糊秆,需要“Stop The World”。
  • 并發(fā)標(biāo)記(CMS concurrent mark):進(jìn)行GC Roots Tracing的過程议双,在整個(gè)過程中耗時(shí)最長痘番。
  • 重新標(biāo)記(CMS remark):為了修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,這個(gè)階段的停頓時(shí)間一般會(huì)比初始標(biāo)記階段稍長一些平痰,但遠(yuǎn)比并發(fā)標(biāo)記的時(shí)間短汞舱。此階段也需要“Stop The World”。
  • 并發(fā)清除(CMS concurrent sweep)

由于整個(gè)過程中耗時(shí)最長的并發(fā)標(biāo)記和并發(fā)清除過程收集器線程都可以與用戶線程一起工作宗雇。

所以昂芜,從總體上來說,CMS收集器的內(nèi)存回收過程是與用戶線程一起并發(fā)執(zhí)行的赔蒲。通過下圖可以比較清楚地看到CMS收集器的運(yùn)作步驟中并發(fā)和需要停頓的時(shí)間:

image.png

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

CMS是一款優(yōu)秀的收集器泌神,它的主要優(yōu)點(diǎn)在名字上已經(jīng)體現(xiàn)出來了:并發(fā)收集良漱、低停頓,因此CMS收集器也被稱為并發(fā)低停頓收集器(Concurrent Low Pause Collector)腻扇。

缺點(diǎn)

  • 對(duì)CPU資源非常敏感 其實(shí)债热,面向并發(fā)設(shè)計(jì)的程序都對(duì)CPU資源比較敏感。在并發(fā)階段幼苛,它雖然不會(huì)導(dǎo)致用戶線程停頓窒篱,但會(huì)因?yàn)檎加昧艘徊糠志€程(或者說CPU資源)而導(dǎo)致應(yīng)用程序變慢,總吞吐量會(huì)降低舶沿。
  • CMS默認(rèn)啟動(dòng)的回收線程數(shù)是(CPU數(shù)量+3)/4墙杯,也就是當(dāng)CPU在4個(gè)以上時(shí),并發(fā)回收時(shí)垃圾收集線程不少于25%的CPU資源括荡,并且隨著CPU數(shù)量的增加而下降高镐。但是當(dāng)CPU不足4個(gè)時(shí)(比如2個(gè)),CMS對(duì)用戶程序的影響就可能變得很大畸冲,如果本來CPU負(fù)載就比較大嫉髓,還要分出一半的運(yùn)算能力去執(zhí)行收集器線程,就可能導(dǎo)致用戶程序的執(zhí)行速度忽然降低了50%邑闲,其實(shí)也讓人無法接受算行。
  • 無法處理浮動(dòng)垃圾(Floating Garbage) 可能出現(xiàn)“Concurrent Mode Failure”失敗而導(dǎo)致另一次Full GC的產(chǎn)生。
  • 由于CMS并發(fā)清理階段用戶線程還在運(yùn)行著苫耸,伴隨程序運(yùn)行自然就還會(huì)有新的垃圾不斷產(chǎn)生州邢。這一部分垃圾出現(xiàn)在標(biāo)記過程之后,CMS無法再當(dāng)次收集中處理掉它們褪子,只好留待下一次GC時(shí)再清理掉量淌。
  • 這一部分垃圾就被稱為“浮動(dòng)垃圾”。也是由于在垃圾收集階段用戶線程還需要運(yùn)行嫌褪,那也就還需要預(yù)留有足夠的內(nèi)存空間給用戶線程使用呀枢,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進(jìn)行收集,需要預(yù)留一部分空間提供并發(fā)收集時(shí)的程序運(yùn)作使用笼痛。
  • 標(biāo)記-清除算法導(dǎo)致的空間碎片 CMS是一款基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器硫狞,這意味著收集結(jié)束時(shí)會(huì)有大量空間碎片產(chǎn)生。
  • 空間碎片過多時(shí)晃痴,將會(huì)給大對(duì)象分配帶來很大麻煩残吩,往往出現(xiàn)老年代空間剩余,但無法找到足夠大連續(xù)空間來分配當(dāng)前對(duì)象倘核。

G1收集器

G1(Garbage-First)收集器是當(dāng)今收集器技術(shù)發(fā)展最前沿的成果之一泣侮,它是一款面向服務(wù)端應(yīng)用的垃圾收集器,HotSpot開發(fā)團(tuán)隊(duì)賦予它的使命是(在比較長期的)未來可以替換掉JDK 1.5中發(fā)布的CMS收集器紧唱。與其他GC收集器相比活尊,G1具備如下特點(diǎn):

  • 并行與并發(fā) G1 能充分利用多CPU隶校、多核環(huán)境下的硬件優(yōu)勢(shì),使用多個(gè)CPU來縮短“Stop The World”停頓時(shí)間蛹锰,部分其他收集器原本需要停頓Java線程執(zhí)行的GC動(dòng)作深胳,G1收集器仍然可以通過并發(fā)的方式讓Java程序繼續(xù)執(zhí)行。
  • 分代收集 與其他收集器一樣铜犬,分代概念在G1中依然得以保留舞终。雖然G1可以不需要其他收集器配合就能獨(dú)立管理整個(gè)GC堆,但它能夠采用不同方式去處理新創(chuàng)建的對(duì)象和已存活一段時(shí)間癣猾、熬過多次GC的舊對(duì)象來獲取更好的收集效果敛劝。
  • 空間整合 G1從整體來看是基于“標(biāo)記-整理”算法實(shí)現(xiàn)的收集器,從局部(兩個(gè)Region之間)上來看是基于“復(fù)制”算法實(shí)現(xiàn)的纷宇。這意味著G1運(yùn)行期間不會(huì)產(chǎn)生內(nèi)存空間碎片夸盟,收集后能提供規(guī)整的可用內(nèi)存。此特性有利于程序長時(shí)間運(yùn)行像捶,分配大對(duì)象時(shí)不會(huì)因?yàn)闊o法找到連續(xù)內(nèi)存空間而提前觸發(fā)下一次GC上陕。
  • 可預(yù)測(cè)的停頓 這是G1相對(duì)CMS的一大優(yōu)勢(shì),降低停頓時(shí)間是G1和CMS共同的關(guān)注點(diǎn)拓春,但G1除了降低停頓外释簿,還能建立可預(yù)測(cè)的停頓時(shí)間模型,能讓使用者明確指定在一個(gè)長度為M毫秒的時(shí)間片段內(nèi)痘儡,消耗在GC上的時(shí)間不得超過N毫秒,這幾乎已經(jīng)是實(shí)時(shí)Java(RTSJ)的垃圾收集器的特征了枢步。

橫跨整個(gè)堆內(nèi)存

在G1之前的其他收集器進(jìn)行收集的范圍都是整個(gè)新生代或者老生代沉删,而G1不再是這樣。對(duì)象都是在堆上分配的嗎醉途?推薦大家看下矾瑰。關(guān)注微信公眾號(hào):Java技術(shù)棧,在后臺(tái)回復(fù):JVM隘擎,可以獲取我整理的 N 篇最新 JVM 教程殴穴,都是干貨。

G1在使用時(shí)货葬,Java堆的內(nèi)存布局與其他收集器有很大區(qū)別采幌,它將整個(gè)Java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域(Region),雖然還保留新生代和老年代的概念震桶,但新生代和老年代不再是物理隔離的了休傍,而都是一部分Region(不需要連續(xù))的集合。

建立可預(yù)測(cè)的時(shí)間模型

G1收集器之所以能建立可預(yù)測(cè)的停頓時(shí)間模型蹲姐,是因?yàn)樗梢杂杏?jì)劃地避免在整個(gè)Java堆中進(jìn)行全區(qū)域的垃圾收集磨取。G1跟蹤各個(gè)Region里面的垃圾堆積的價(jià)值大腥耸痢(回收所獲得的空間大小以及回收所需時(shí)間的經(jīng)驗(yàn)值),在后臺(tái)維護(hù)一個(gè)優(yōu)先列表忙厌,每次根據(jù)允許的收集時(shí)間凫岖,優(yōu)先回收價(jià)值最大的Region(這也就是Garbage-First名稱的來由)。這種使用Region劃分內(nèi)存空間以及有優(yōu)先級(jí)的區(qū)域回收方式逢净,保證了G1收集器在有限的時(shí)間內(nèi)可以獲取盡可能高的收集效率哥放。

避免全堆掃描——Remembered Set

G1把Java堆分為多個(gè)Region,就是“化整為零”汹胃。但是Region不可能是孤立的婶芭,一個(gè)對(duì)象分配在某個(gè)Region中,可以與整個(gè)Java堆任意的對(duì)象發(fā)生引用關(guān)系着饥。在做可達(dá)性分析確定對(duì)象是否存活的時(shí)候犀农,需要掃描整個(gè)Java堆才能保證準(zhǔn)確性,這顯然是對(duì)GC效率的極大傷害宰掉。

為了避免全堆掃描的發(fā)生呵哨,虛擬機(jī)為G1中每個(gè)Region維護(hù)了一個(gè)與之對(duì)應(yīng)的Remembered Set。虛擬機(jī)發(fā)現(xiàn)程序在對(duì)Reference類型的數(shù)據(jù)進(jìn)行寫操作時(shí)轨奄,會(huì)產(chǎn)生一個(gè)Write Barrier暫時(shí)中斷寫操作孟害。

檢查Reference引用的對(duì)象是否處于不同的Region之中(在分代的例子中就是檢查是否老年代中的對(duì)象引用了新生代中的對(duì)象),如果是挪拟,便通過CardTable把相關(guān)引用信息記錄到被引用對(duì)象所屬的Region的Remembered Set之中挨务。當(dāng)進(jìn)行內(nèi)存回收時(shí),在GC根節(jié)點(diǎn)的枚舉范圍中加入Remembered Set即可保證不對(duì)全堆掃描也不會(huì)有遺漏玉组。

如果不計(jì)算維護(hù)Remembered Set的操作谎柄,G1收集器的運(yùn)作大致可劃分為以下幾個(gè)步驟:

  • 初始標(biāo)記(Initial Marking) 僅僅只是標(biāo)記一下GC Roots 能直接關(guān)聯(lián)到的對(duì)象,并且修改TAMS(Nest Top Mark Start)的值惯雳,讓下一階段用戶程序并發(fā)運(yùn)行時(shí)朝巫,能在正確可以的Region中創(chuàng)建對(duì)象,此階段需要停頓線程石景,但耗時(shí)很短劈猿。
  • 并發(fā)標(biāo)記(Concurrent Marking) 從GC Root 開始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析,找到存活對(duì)象潮孽,此階段耗時(shí)較長揪荣,但可與用戶程序并發(fā)執(zhí)行。
  • 最終標(biāo)記(Final Marking) 為了修正在并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分標(biāo)記記錄往史,虛擬機(jī)將這段時(shí)間對(duì)象變化記錄在線程的Remembered Set Logs里面变逃,最終標(biāo)記階段需要把Remembered Set Logs的數(shù)據(jù)合并到Remembered Set中,這階段需要停頓線程怠堪,但是可并行執(zhí)行揽乱。
  • 篩選回收(Live Data Counting and Evacuation) 首先對(duì)各個(gè)Region中的回收價(jià)值和成本進(jìn)行排序名眉,根據(jù)用戶所期望的GC 停頓是時(shí)間來制定回收計(jì)劃。此階段其實(shí)也可以做到與用戶程序一起并發(fā)執(zhí)行凰棉,但是因?yàn)橹换厥找徊糠諶egion损拢,時(shí)間是用戶可控制的,而且停頓用戶線程將大幅度提高收集效率撒犀。

通過下圖可以比較清楚地看到G1收集器的運(yùn)作步驟中并發(fā)和需要停頓的階段(Safepoint處):

image.png

總結(jié)

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末福压,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子或舞,更是在濱河造成了極大的恐慌荆姆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件映凳,死亡現(xiàn)場(chǎng)離奇詭異胆筒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诈豌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門仆救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人矫渔,你說我怎么就攤上這事彤蔽。” “怎么了庙洼?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵顿痪,是天一觀的道長。 經(jīng)常有香客問我油够,道長蚁袭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任叠聋,我火速辦了婚禮撕阎,結(jié)果婚禮上受裹,老公的妹妹穿的比我還像新娘碌补。我一直安慰自己,他們只是感情好棉饶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布厦章。 她就那樣靜靜地躺著,像睡著了一般照藻。 火紅的嫁衣襯著肌膚如雪袜啃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天幸缕,我揣著相機(jī)與錄音群发,去河邊找鬼晰韵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛熟妓,可吹牛的內(nèi)容都是我干的雪猪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼起愈,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼只恨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抬虽,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤官觅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后阐污,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體休涤,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年疤剑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滑绒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隘膘,死狀恐怖疑故,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弯菊,我是刑警寧澤纵势,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站管钳,受9級(jí)特大地震影響钦铁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜才漆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一牛曹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧醇滥,春花似錦黎比、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至不跟,卻和暖如春颓帝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工购城, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吕座,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓瘪板,卻偏偏與公主長得像,于是被迫代替她去往敵國和親篷帅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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