JDK12 ShenandoahGC小試牛刀

本文主要試用一下JDK12新引入的ShenandoahGC

ShenandoahGC

Shenandoah是一款concurrent及parallel的垃圾收集器


  • 跟ZGC一樣也是面向low-pause-time的垃圾收集器,不過(guò)ZGC是基于colored pointers來(lái)實(shí)現(xiàn),而Shenandoah GC是基于brooks pointers來(lái)實(shí)現(xiàn)
  • 與G1 GC相比,G1的evacuation是parallel的但不是concurrent宪拥,而Shenandoah的evacuation是concurrent晓淀,因而能更好地減少pause time
  • 與G1 GC一樣,ShenandoahGC也是基于region的GC,不同的是ShenandoahGC在邏輯上沒(méi)有分代锡垄,因而就沒(méi)有young/old

GC cycle

ShenandoahGC主要有如下幾個(gè)階段:


Snapshot-at-the-beginning concurrent mark

這里包含Init Mark(Pause)、Concurrent Mark祭隔、Final Mark(Pause)货岭;這里使用到了White(not yet visited)、Gray(visited, but references are not scanned yet)疾渴、Black(visited, and fully scanned) Color算法進(jìn)行mark

Concurrent evacuation

這個(gè)就是與G1不同的evacuation階段千贯,它是concurrent的;這里用到了Brooks Pointers(object version change with additional atomically changed indirection)算法進(jìn)行copy搞坝,

Concurrent update references (optional)

這里包含Init update Refs(Pause)搔谴、Concurrent update Refs、Final update Refs(Pause)
Final Mark或者Final update Refs之后都可能進(jìn)行Concurrent cleanup桩撮,進(jìn)行垃圾回收敦第,reclaims region

相關(guān)參數(shù)

Shenandoah開(kāi)頭的參數(shù)

     bool ShenandoahAcmpBarrier                    = true                                   {diagnostic} {default}
     bool ShenandoahAllocFailureALot               = false                                  {diagnostic} {default}
    uintx ShenandoahAllocSpikeFactor               = 5                                    {experimental} {default}
     intx ShenandoahAllocationStallThreshold       = 10000                                  {diagnostic} {default}
    uintx ShenandoahAllocationThreshold            = 0                                    {experimental} {default}
     bool ShenandoahAllocationTrace                = false                                  {diagnostic} {default}
     bool ShenandoahAllowMixedAllocs               = true                                   {diagnostic} {default}
     bool ShenandoahAlwaysClearSoftRefs            = false                                {experimental} {default}
     bool ShenandoahAlwaysPreTouch                 = false                                  {diagnostic} {default}
     bool ShenandoahCASBarrier                     = true                                   {diagnostic} {default}
     bool ShenandoahCloneBarrier                   = true                                   {diagnostic} {default}
    uintx ShenandoahCodeRootsStyle                 = 2                                    {experimental} {default}
     bool ShenandoahCommonGCStateLoads             = false                                {experimental} {default}
     bool ShenandoahConcurrentScanCodeRoots        = true                                 {experimental} {default}
    uintx ShenandoahControlIntervalAdjustPeriod    = 1000                                 {experimental} {default}
    uintx ShenandoahControlIntervalMax             = 10                                   {experimental} {default}
    uintx ShenandoahControlIntervalMin             = 1                                    {experimental} {default}
    uintx ShenandoahCriticalFreeThreshold          = 1                                    {experimental} {default}
     bool ShenandoahDecreaseRegisterPressure       = false                                  {diagnostic} {default}
     bool ShenandoahDegeneratedGC                  = true                                   {diagnostic} {default}
     bool ShenandoahDontIncreaseWBFreq             = true                                 {experimental} {default}
     bool ShenandoahElasticTLAB                    = true                                   {diagnostic} {default}
    uintx ShenandoahEvacAssist                     = 10                                   {experimental} {default}
    uintx ShenandoahEvacReserve                    = 5                                    {experimental} {default}
     bool ShenandoahEvacReserveOverflow            = true                                 {experimental} {default}
   double ShenandoahEvacWaste                      = 1.200000                             {experimental} {default}
    uintx ShenandoahFreeThreshold                  = 10                                   {experimental} {default}
    uintx ShenandoahFullGCThreshold                = 3                                    {experimental} {default}
    ccstr ShenandoahGCHeuristics                   = adaptive                             {experimental} {default}
    uintx ShenandoahGarbageThreshold               = 60                                   {experimental} {default}
    uintx ShenandoahGuaranteedGCInterval           = 300000                               {experimental} {default}
   size_t ShenandoahHeapRegionSize                 = 0                                    {experimental} {default}
     bool ShenandoahHumongousMoves                 = true                                 {experimental} {default}
     intx ShenandoahHumongousThreshold             = 100                                  {experimental} {default}
    uintx ShenandoahImmediateThreshold             = 90                                   {experimental} {default}
     bool ShenandoahImplicitGCInvokesConcurrent    = true                                 {experimental} {default}
    uintx ShenandoahInitFreeThreshold              = 70                                   {experimental} {default}
     bool ShenandoahKeepAliveBarrier               = true                                   {diagnostic} {default}
    uintx ShenandoahLearningSteps                  = 5                                    {experimental} {default}
     bool ShenandoahLoopOptsAfterExpansion         = true                                 {experimental} {default}
    uintx ShenandoahMarkLoopStride                 = 1000                                 {experimental} {default}
     intx ShenandoahMarkScanPrefetch               = 32                                   {experimental} {default}
   size_t ShenandoahMaxRegionSize                  = 33554432                             {experimental} {default}
    uintx ShenandoahMergeUpdateRefsMaxGap          = 200                                  {experimental} {default}
    uintx ShenandoahMergeUpdateRefsMinGap          = 100                                  {experimental} {default}
    uintx ShenandoahMinFreeThreshold               = 10                                   {experimental} {default}
   size_t ShenandoahMinRegionSize                  = 262144                               {experimental} {default}
     bool ShenandoahOOMDuringEvacALot              = false                                  {diagnostic} {default}
     bool ShenandoahOptimizeInstanceFinals         = false                                {experimental} {default}
     bool ShenandoahOptimizeStableFinals           = false                                {experimental} {default}
     bool ShenandoahOptimizeStaticFinals           = true                                 {experimental} {default}
     bool ShenandoahPacing                         = true                                 {experimental} {default}
    uintx ShenandoahPacingCycleSlack               = 10                                   {experimental} {default}
    uintx ShenandoahPacingIdleSlack                = 2                                    {experimental} {default}
    uintx ShenandoahPacingMaxDelay                 = 10                                   {experimental} {default}
   double ShenandoahPacingSurcharge                = 1.100000                             {experimental} {default}
    uintx ShenandoahParallelRegionStride           = 1024                                 {experimental} {default}
     uint ShenandoahParallelSafepointThreads       = 4                                    {experimental} {default}
     bool ShenandoahPreclean                       = true                                 {experimental} {default}
     bool ShenandoahReadBarrier                    = true                                   {diagnostic} {default}
    uintx ShenandoahRefProcFrequency               = 5                                    {experimental} {default}
     bool ShenandoahRegionSampling                 = true                                 {experimental} {command line}
      int ShenandoahRegionSamplingRate             = 40                                   {experimental} {default}
     bool ShenandoahSATBBarrier                    = true                                   {diagnostic} {default}
    uintx ShenandoahSATBBufferFlushInterval        = 100                                  {experimental} {default}
   size_t ShenandoahSATBBufferSize                 = 1024                                 {experimental} {default}
     bool ShenandoahStoreCheck                     = false                                  {diagnostic} {default}
     bool ShenandoahStoreValEnqueueBarrier         = false                                  {diagnostic} {default}
     bool ShenandoahStoreValReadBarrier            = true                                   {diagnostic} {default}
     bool ShenandoahSuspendibleWorkers             = false                                {experimental} {default}
   size_t ShenandoahTargetNumRegions               = 2048                                 {experimental} {default}
     bool ShenandoahTerminationTrace               = false                                  {diagnostic} {default}
     bool ShenandoahUncommit                       = true                                 {experimental} {default}
    uintx ShenandoahUncommitDelay                  = 300000                               {experimental} {default}
    uintx ShenandoahUnloadClassesFrequency         = 0                                    {experimental} {default}
    ccstr ShenandoahUpdateRefsEarly                = adaptive                             {experimental} {default}
     bool ShenandoahVerify                         = false                                  {diagnostic} {default}
     intx ShenandoahVerifyLevel                    = 4                                      {diagnostic} {default}
     bool ShenandoahWriteBarrier                   = true                                   {diagnostic} {default}

其中有一些是diagnostic用的,比如ShenandoahAcmpBarrier店量、ShenandoahAllocFailureALot芜果、ShenandoahAllocationStallThreshold等

Heuristics相關(guān)參數(shù)

    ccstr ShenandoahGCHeuristics                   = adaptive                             {experimental} {default}
    uintx ShenandoahInitFreeThreshold              = 70                                   {experimental} {default}
    uintx ShenandoahMinFreeThreshold               = 10                                   {experimental} {default}
    uintx ShenandoahAllocSpikeFactor               = 5                                    {experimental} {default}
    uintx ShenandoahGarbageThreshold               = 60                                   {experimental} {default}
    uintx ShenandoahFreeThreshold                  = 10                                   {experimental} {default}
    uintx ShenandoahAllocationThreshold            = 0                                    {experimental} {default}
    ccstr ShenandoahUpdateRefsEarly                = adaptive                             {experimental} {default}

Heuristics主要用于告訴Shenandoah何時(shí)啟動(dòng)一個(gè)GC cycle,其中ShenandoahGCHeuristics用于選擇不同的策略融师,其可選值有adaptive(默認(rèn))右钾、static、compact旱爆、passive(diagnostic用)舀射、aggressive(diagnostic用)

  • adaptive方式主要通過(guò)ShenandoahInitFreeThreshold(Initial remaining free heap threshold for learning steps)、ShenandoahMinFreeThreshold(free space threshold at which heuristics triggers the GC unconditionally)怀伦、ShenandoahAllocSpikeFactor(How much heap to reserve for absorbing allocation spikes)脆烟、XX:ShenandoahGarbageThreshold(Sets the percentage of garbage a region need to contain before it can be marked for collection)來(lái)設(shè)置合適啟動(dòng)GC cycle
  • static方式主要是基于heap occupancy以及allocation pressure來(lái)決定是否啟動(dòng)GC cycle,相關(guān)參數(shù)有:ShenandoahFreeThreshold(Set the percentage of free heap at which a GC cycle is started)房待、ShenandoahAllocationThreshold(Set percentage of memory allocated since last GC cycle before a new GC cycle is started)邢羔、ShenandoahGarbageThreshold
  • compact方式是continuous方式的,只要有allocation發(fā)生吴攒,上一個(gè)GC cycle結(jié)束之后就啟動(dòng)新的GC cycle张抄,相關(guān)參數(shù)有ConcGCThreads(Trim down the number of concurrent GC threads to make more room for application to run)、ShenandoahAllocationThreshold
  • passive方式是完全passive洼怔,當(dāng)內(nèi)存耗盡時(shí)觸發(fā)STW署惯,通常用于diagnostic
  • aggressive方式是完全active的,上一個(gè)GC cycle結(jié)束之后就啟動(dòng)新的GC cycle(有點(diǎn)類(lèi)似compact方式)镣隶,不過(guò)它會(huì)evacuate所有的live objects极谊,通常用于diagnostic

Failure Modes

當(dāng)allocation failure發(fā)生的時(shí)候诡右,Shenandoah有一些優(yōu)雅的degradation ladder用于處理這種情況,如下:

  • Pacing(<10 ms)

ShenandoahPacing參數(shù)默認(rèn)開(kāi)啟轻猖,Pacer用于在gc不夠快的時(shí)候去stall正在分配對(duì)象的線程帆吻,當(dāng)gc速度跟上來(lái)了就解除對(duì)這些線程的stall;stall不是無(wú)期限的咙边,有個(gè)ShenandoahPacingMaxDelay(單位毫秒)參數(shù)可以設(shè)置猜煮,一旦超過(guò)該值allocation就會(huì)產(chǎn)生。當(dāng)allocation壓力大的時(shí)候败许,Pacer就無(wú)能為力了王带,這個(gè)時(shí)候就會(huì)進(jìn)入下一個(gè)step

  • Degenerated GC(<100 ms)

ShenandoahDegeneratedGC參數(shù)默認(rèn)開(kāi)啟,在這個(gè)Degenerated cycle市殷,Shenandoah使用的線程數(shù)取之于ParallelGCThreads而非ConcCGThreads

  • Full GC(>100 ms)

當(dāng)Degenerated GC之后還沒(méi)有足夠的內(nèi)存愕撰,則進(jìn)入Full GC cycle,它會(huì)盡可能地進(jìn)行compact然后釋放內(nèi)存以確保不發(fā)生OOM

實(shí)例

啟動(dòng)參數(shù)

-server -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UsePerfData -XX:+ShenandoahRegionSampling -XX:ParallelGCThreads=4 -XX:ConcGCThreads=4 -XX:+UnlockDiagnosticVMOptions -Xlog:age*,ergo*,gc*=info

gc日志

[2019-03-21T15:12:53.771-0800][8707][gc] Consider -XX:+ClassUnloadingWithConcurrentMark if large pause times are observed on class-unloading sensitive workloads
[2019-03-21T15:12:53.862-0800][8707][gc,init] Regions: 2048 x 1024K
[2019-03-21T15:12:53.862-0800][8707][gc,init] Humongous object threshold: 1024K
[2019-03-21T15:12:53.863-0800][8707][gc,init] Max TLAB size: 1024K
[2019-03-21T15:12:53.863-0800][8707][gc,init] GC threads: 4 parallel, 4 concurrent
[2019-03-21T15:12:53.863-0800][8707][gc,init] Reference processing: parallel
[2019-03-21T15:12:53.864-0800][8707][gc     ] Heuristics ergonomically sets -XX:+ExplicitGCInvokesConcurrent
[2019-03-21T15:12:53.864-0800][8707][gc     ] Heuristics ergonomically sets -XX:+ShenandoahImplicitGCInvokesConcurrent
[2019-03-21T15:12:53.864-0800][8707][gc,init] Shenandoah heuristics: adaptive
[2019-03-21T15:12:53.864-0800][8707][gc,heap] Initialize Shenandoah heap with initial size 128M
[2019-03-21T15:12:53.865-0800][8707][gc,ergo] Pacer for Idle. Initial: 40M, Alloc Tax Rate: 1.0x
[2019-03-21T15:12:53.883-0800][8707][gc,init] Safepointing mechanism: global-page poll
[2019-03-21T15:12:53.883-0800][8707][gc     ] Using Shenandoah
[2019-03-21T15:12:53.884-0800][8707][gc,heap,coops] Heap address: 0x0000000780000000, size: 2048 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[2019-03-21T15:12:59.530-0800][14083][gc           ] Trigger: Metadata GC Threshold
[2019-03-21T15:12:59.532-0800][14083][gc,ergo      ] Free: 1813M (1813 regions), Max regular: 1024K, Max humongous: 1855488K, External frag: 1%, Internal frag: 0%
[2019-03-21T15:12:59.532-0800][14083][gc,ergo      ] Evacuation Reserve: 103M (103 regions), Max regular: 1024K
[2019-03-21T15:12:59.532-0800][14083][gc,start     ] GC(0) Concurrent reset
[2019-03-21T15:12:59.533-0800][14083][gc,task      ] GC(0) Using 4 of 4 workers for concurrent reset
[2019-03-21T15:12:59.533-0800][14083][gc           ] GC(0) Concurrent reset 132M->132M(2048M) 0.441ms
[2019-03-21T15:12:59.533-0800][15619][gc,start     ] GC(0) Pause Init Mark (process weakrefs) (unload classes)
[2019-03-21T15:12:59.533-0800][15619][gc,task      ] GC(0) Using 4 of 4 workers for init marking
[2019-03-21T15:12:59.541-0800][15619][gc,ergo      ] GC(0) Pacer for Mark. Expected Live: 204M, Free: 1813M, Non-Taxable: 181M, Alloc Tax Rate: 0.4x
[2019-03-21T15:12:59.541-0800][15619][gc           ] GC(0) Pause Init Mark (process weakrefs) (unload classes) 7.568ms
[2019-03-21T15:12:59.541-0800][14083][gc,start     ] GC(0) Concurrent marking (process weakrefs) (unload classes)
[2019-03-21T15:12:59.541-0800][14083][gc,task      ] GC(0) Using 4 of 4 workers for concurrent marking
[2019-03-21T15:12:59.619-0800][14083][gc           ] GC(0) Concurrent marking (process weakrefs) (unload classes) 132M->134M(2048M) 78.373ms
[2019-03-21T15:12:59.619-0800][14083][gc,start     ] GC(0) Concurrent precleaning
[2019-03-21T15:12:59.619-0800][14083][gc,task      ] GC(0) Using 1 of 4 workers for concurrent preclean
[2019-03-21T15:12:59.622-0800][14083][gc           ] GC(0) Concurrent precleaning 134M->134M(2048M) 2.397ms
[2019-03-21T15:12:59.622-0800][15619][gc,start     ] GC(0) Pause Final Mark (process weakrefs) (unload classes)
[2019-03-21T15:12:59.622-0800][15619][gc,task      ] GC(0) Using 4 of 4 workers for final marking
[2019-03-21T15:12:59.625-0800][15619][gc,stringtable] GC(0) Cleaned string table, strings: 13692 processed, 50 removed
[2019-03-21T15:12:59.626-0800][15619][gc,ergo       ] GC(0) Adaptive CSet Selection. Target Free: 204M, Actual Free: 1914M, Max CSet: 85M, Min Garbage: 0M
[2019-03-21T15:12:59.626-0800][15619][gc,ergo       ] GC(0) Collectable Garbage: 117M (97% of total), 8M CSet, 126 CSet regions
[2019-03-21T15:12:59.626-0800][15619][gc,ergo       ] GC(0) Immediate Garbage: 0M (0% of total), 0 regions
[2019-03-21T15:12:59.626-0800][15619][gc,ergo       ] GC(0) Pacer for Evacuation. Used CSet: 126M, Free: 1811M, Non-Taxable: 181M, Alloc Tax Rate: 1.1x
[2019-03-21T15:12:59.626-0800][15619][gc            ] GC(0) Pause Final Mark (process weakrefs) (unload classes) 4.712ms
[2019-03-21T15:12:59.626-0800][14083][gc,start      ] GC(0) Concurrent cleanup
[2019-03-21T15:12:59.627-0800][14083][gc            ] GC(0) Concurrent cleanup 134M->135M(2048M) 0.132ms
[2019-03-21T15:12:59.627-0800][14083][gc,ergo       ] GC(0) Free: 1810M (1810 regions), Max regular: 1024K, Max humongous: 1852416K, External frag: 1%, Internal frag: 0%
[2019-03-21T15:12:59.627-0800][14083][gc,ergo       ] GC(0) Evacuation Reserve: 102M (103 regions), Max regular: 1024K
[2019-03-21T15:12:59.627-0800][14083][gc,start      ] GC(0) Concurrent evacuation
[2019-03-21T15:12:59.627-0800][14083][gc,task       ] GC(0) Using 4 of 4 workers for concurrent evacuation
[2019-03-21T15:12:59.643-0800][14083][gc            ] GC(0) Concurrent evacuation 135M->145M(2048M) 15.912ms
[2019-03-21T15:12:59.643-0800][15619][gc,start      ] GC(0) Pause Init Update Refs
[2019-03-21T15:12:59.643-0800][15619][gc,ergo       ] GC(0) Pacer for Update Refs. Used: 145M, Free: 1810M, Non-Taxable: 181M, Alloc Tax Rate: 1.1x
[2019-03-21T15:12:59.643-0800][15619][gc            ] GC(0) Pause Init Update Refs 0.090ms
[2019-03-21T15:12:59.643-0800][14083][gc,start      ] GC(0) Concurrent update references
[2019-03-21T15:12:59.643-0800][14083][gc,task       ] GC(0) Using 4 of 4 workers for concurrent reference update
[2019-03-21T15:12:59.652-0800][14083][gc            ] GC(0) Concurrent update references 145M->147M(2048M) 9.028ms
[2019-03-21T15:12:59.652-0800][15619][gc,start      ] GC(0) Pause Final Update Refs
[2019-03-21T15:12:59.652-0800][15619][gc,task       ] GC(0) Using 4 of 4 workers for final reference update
[2019-03-21T15:12:59.653-0800][15619][gc            ] GC(0) Pause Final Update Refs 0.489ms
[2019-03-21T15:12:59.653-0800][14083][gc,start      ] GC(0) Concurrent cleanup
[2019-03-21T15:12:59.653-0800][14083][gc            ] GC(0) Concurrent cleanup 147M->21M(2048M) 0.088ms
[2019-03-21T15:12:59.653-0800][14083][gc,ergo       ] Free: 1924M (1924 regions), Max regular: 1024K, Max humongous: 1840128K, External frag: 7%, Internal frag: 0%
[2019-03-21T15:12:59.653-0800][14083][gc,ergo       ] Evacuation Reserve: 103M (103 regions), Max regular: 1024K
[2019-03-21T15:12:59.653-0800][14083][gc,ergo       ] Pacer for Idle. Initial: 40M, Alloc Tax Rate: 1.0x
[2019-03-21T15:17:59.666-0800][14083][gc            ] Trigger: Time since last GC (300009 ms) is larger than guaranteed interval (300000 ms)

gc visualizer

有個(gè)shenandoah-visualizer工具可以用來(lái)可視化ShenandoahGC醋寝,可視化效果如下:

小結(jié)

  • Shenandoah是一款concurrent及parallel的垃圾收集器搞挣;跟ZGC一樣也是面向low-pause-time的垃圾收集器,不過(guò)ZGC是基于colored pointers來(lái)實(shí)現(xiàn)音羞,而Shenandoah GC是基于brooks pointers來(lái)實(shí)現(xiàn)囱桨;與G1 GC相比,G1的evacuation是parallel的但不是concurrent黄选,而Shenandoah的evacuation是concurrent蝇摸,因而能更好地減少pause time;與G1 GC一樣办陷,ShenandoahGC也是基于region的GC,不同的是ShenandoahGC在邏輯上沒(méi)有分代律歼,因而就沒(méi)有young/old
  • Shenandoah的GC cycle主要有Snapshot-at-the-beginning concurrent mark包括Init Mark(Pause)民镜、Concurrent Mark、Final Mark(Pause)险毁、Concurrent evacuation制圈、Concurrent update references (optional)包括Init update Refs(Pause)、Concurrent update Refs畔况、Final update Refs(Pause)鲸鹦;其中Final Mark或者Final update Refs之后都可能進(jìn)行Concurrent cleanup,進(jìn)行垃圾回收跷跪,reclaims region
  • Heuristics主要用于告訴Shenandoah何時(shí)啟動(dòng)一個(gè)GC馋嗜,其中ShenandoahGCHeuristics用于選擇不同的策略,其可選值有adaptive(默認(rèn))吵瞻、static葛菇、compact甘磨、passive(diagnostic用)、aggressive(diagnostic用)眯停;另外當(dāng)allocation failure發(fā)生的時(shí)候济舆,Shenandoah有一些優(yōu)雅的degradation ladder用于處理這種情況,包括Pacing(<10 ms)莺债、Degenerated GC(<100 ms)滋觉、Full GC(>100 ms)

doc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市齐邦,隨后出現(xiàn)的幾起案子椎瘟,更是在濱河造成了極大的恐慌,老刑警劉巖侄旬,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肺蔚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡儡羔,警方通過(guò)查閱死者的電腦和手機(jī)宣羊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)汰蜘,“玉大人仇冯,你說(shuō)我怎么就攤上這事∽宀伲” “怎么了苛坚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)色难。 經(jīng)常有香客問(wèn)我泼舱,道長(zhǎng),這世上最難降的妖魔是什么枷莉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任娇昙,我火速辦了婚禮,結(jié)果婚禮上笤妙,老公的妹妹穿的比我還像新娘冒掌。我一直安慰自己,他們只是感情好蹲盘,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布股毫。 她就那樣靜靜地躺著,像睡著了一般召衔。 火紅的嫁衣襯著肌膚如雪铃诬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音氧急,去河邊找鬼颗胡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吩坝,可吹牛的內(nèi)容都是我干的毒姨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼钉寝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼弧呐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起嵌纲,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俘枫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后逮走,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸠蚪,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年师溅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茅信。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡墓臭,死狀恐怖蘸鲸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窿锉,我是刑警寧澤酌摇,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站嗡载,受9級(jí)特大地震影響窑多,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鼻疮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一怯伊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧判沟,春花似錦、人聲如沸崭篡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)琉闪。三九已至迹炼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斯入。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工砂碉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刻两。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓增蹭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親磅摹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滋迈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359