誰(shuí)動(dòng)了我的內(nèi)存何乎,揭秘Android OOM崩潰下降90%的秘密

最近一直在做內(nèi)存和 ANR 相關(guān)的優(yōu)化饵较,接下來(lái)我將會(huì)花幾篇文章梳理一下內(nèi)存相關(guān)的優(yōu)化竹观,以及我是如何將 OOM 崩潰率下降 90%镐捧。

今天這篇文章主要介紹內(nèi)存相關(guān)的知識(shí)點(diǎn),以及那些因素會(huì)導(dǎo)致 OOM 崩潰和相對(duì)應(yīng)的解決方案臭增,所以通過這篇文章你將學(xué)習(xí)到以下內(nèi)容:

  • 什么是虛擬內(nèi)存和物理內(nèi)存
  • 32 位和 64 位設(shè)備可用虛擬內(nèi)存分別是多少
  • 為什么虛擬內(nèi)存不足主要發(fā)生在 32 位的設(shè)備上
  • 如何解決虛擬內(nèi)存不足的問題
  • App 啟動(dòng)完成之后懂酱,虛擬內(nèi)存的分布
  • 如何解決 Java 堆內(nèi)存不足的問題
  • Java 堆上還有很多可用的內(nèi)存,為什么還會(huì)出現(xiàn) OOM
  • 做性能優(yōu)化時(shí)誊抛,需要關(guān)心那些指標(biāo)數(shù)據(jù)

不知道小伙伴們有沒有經(jīng)歷過列牺,相同的優(yōu)化方案,A 應(yīng)用上線之后拗窃,崩潰率下降很多瞎领,但是 B 應(yīng)用上線只有一點(diǎn)點(diǎn)收益,每個(gè)優(yōu)化方案随夸,在不同的 App 上所得到的優(yōu)化效果未必一樣九默,因?yàn)槊總€(gè) App 在不同的國(guó)家和地區(qū)面對(duì)的用戶群體不一樣,因此機(jī)型也都不一樣宾毒,所以我們需要了解內(nèi)存相關(guān)的知識(shí)點(diǎn)驼修,結(jié)合線上和線下數(shù)據(jù),對(duì)自己的 App 進(jìn)行歸因诈铛,對(duì)癥下藥乙各,才能取得較大的收益。

內(nèi)存是極其稀缺的資源幢竹,不合理的使用會(huì)導(dǎo)致可用內(nèi)存越來(lái)越少觅丰,可能會(huì)引發(fā)卡頓、ANR妨退、OOM 崩潰妇萄、Native 崩潰等等,嚴(yán)重影響用戶的體驗(yàn)咬荷。所以當(dāng)我們?cè)谧鲂阅軆?yōu)化的時(shí)候冠句,內(nèi)存優(yōu)化是非常重要的環(huán)節(jié)。

初期在做內(nèi)存優(yōu)化的時(shí)候幸乒,在我們的腦海里都會(huì)有一個(gè)潛意識(shí)「內(nèi)存占用越少越好」懦底,在某些情況下是不對(duì)的。例如在高端機(jī)上我們可以多分配點(diǎn)內(nèi)存罕扎,可以提升用戶的體驗(yàn)聚唐,但是在低端機(jī)上內(nèi)存本身就很小丐重,所以我們應(yīng)盡量減少內(nèi)存的分配。例如針對(duì)損耗性能的動(dòng)畫杆查、特效等等扮惦,在低端機(jī)上是不是可以關(guān)掉,或者關(guān)掉硬件加速亲桦、采用其他的方案代替崖蜜,這樣不僅可以減少崩潰,還可以減少卡頓客峭,提高用戶體驗(yàn)豫领。

因?yàn)?Java 有自動(dòng)回收機(jī)制,所以在開發(fā)過程中舔琅,很少有人會(huì)去關(guān)心內(nèi)存問題等恐,在腦海中都會(huì)有一個(gè)潛意識(shí) GC 會(huì)自動(dòng)回收,所以用完不會(huì)主動(dòng)釋放掉無(wú)用資源例如 Bitmap备蚓、動(dòng)畫课蔬、播放器等等,等待 GC 來(lái)回收星著,在實(shí)際項(xiàng)目中,依賴 GC 是不可靠的粗悯。首先 GC 自動(dòng)回收機(jī)制具有不確定性虚循,GC 也分為了不同的類型,如果發(fā)生 Full GC 時(shí)样傍,會(huì)觸發(fā) stop the work 事件横缔,會(huì)使 App 變得更加嚴(yán)重。

另外 GC 的回收機(jī)制根據(jù)可達(dá)性分析算法判斷一個(gè)對(duì)象是否可以被回收衫哥,如果存在內(nèi)存泄露茎刚,GC 是不會(huì)回收這些資源的,逐漸累積撤逢,當(dāng)達(dá)到堆的內(nèi)存上限時(shí)膛锭,發(fā)生 OOM 崩潰了,所以你要保證自己不要寫出內(nèi)存泄露的代碼蚊荣,以及團(tuán)隊(duì)其他人不要寫出內(nèi)存泄露的代碼初狰,然而實(shí)際情況這是不可能的,所以依靠 GC 自動(dòng)回收機(jī)制這種想法是不可靠的互例。雖然 Java 有內(nèi)存回收機(jī)制奢入,但是我們應(yīng)該在腦海中保留內(nèi)存管理的意識(shí),所以當(dāng)申請(qǐng)完內(nèi)存媳叨,退出或者不在使用時(shí)腥光,及時(shí)釋放掉內(nèi)存关顷。真正做到 用時(shí)分配,及時(shí)釋放武福。

可用內(nèi)存越來(lái)越少時(shí)议双,嚴(yán)重時(shí)會(huì)導(dǎo)致 OOM 崩潰,做過 OOM 優(yōu)化的朋友應(yīng)該會(huì)發(fā)現(xiàn)艘儒,線上捕獲的大部分 OOM 崩潰堆棧聋伦,都是壓死駱駝的最后一根稻草,并不是問題的根本所在界睁,所以我們需要對(duì) OOM 崩潰進(jìn)行歸因觉增,找到占用內(nèi)存的大頭。降低整機(jī)已使用的內(nèi)存翻斟,從而降低 OOM 崩潰逾礁,因此我大概分為了以下幾個(gè)方面。

  • 虛擬內(nèi)存和物理內(nèi)存
  • 堆內(nèi)存
    • Java 堆內(nèi)存溢出
      • 分配的內(nèi)存到達(dá) Java 堆的上限
      • 可用內(nèi)存很多访惜,因?yàn)閮?nèi)存碎片化嘹履,沒有足夠的連續(xù)段的空間分配
      • 對(duì)象的單次分配或者多次分配累計(jì)過大,例如在循環(huán)動(dòng)畫中一直創(chuàng)建 Bitmap
    • 內(nèi)存泄露
      • 堆內(nèi)存泄露债热,指的是在程序運(yùn)行時(shí)砾嫉,給對(duì)象分配的內(nèi)存,當(dāng)程序退出或者退出界面時(shí)窒篱,分配的內(nèi)存沒有釋放或者因?yàn)槠渌驘o(wú)法釋放
      • 資源泄露焕刮,比如 FD、socket墙杯、線程等等配并,這些在每個(gè)手機(jī)上都是有數(shù)量的限制,如果使用了不釋放高镐,就會(huì)因?yàn)橘Y源的耗盡而崩潰溉旋,我們?cè)诰€上就出現(xiàn)過 FD 的泄露,導(dǎo)致崩潰率漲了 3 倍
  • FD 的數(shù)量超出當(dāng)前手機(jī)的閾值
  • 線程的數(shù)量超出當(dāng)前手機(jī)的閾值

其中 FD 和線程崩潰占比很低嫉髓,因此這不是我們前期優(yōu)化的重點(diǎn)观腊。這篇文章我們重點(diǎn)介紹 虛擬內(nèi)存和物理內(nèi)存,下篇文章將會(huì)介紹堆內(nèi)存算行, 堆內(nèi)存是程序在運(yùn)行過程中為對(duì)象分配內(nèi)存的區(qū)域恕沫,它也屬于虛擬內(nèi)存的范圍。

虛擬內(nèi)存和物理內(nèi)存

介紹虛擬內(nèi)存之前纱意,我們需要先介紹物理內(nèi)存婶溯,物理內(nèi)存就是實(shí)實(shí)在在的內(nèi)存(即內(nèi)存條),如果應(yīng)用直接對(duì)物理內(nèi)存操作,會(huì)存在很多問題:

  • 安全問題迄委,應(yīng)用之間的內(nèi)存空間沒有隔離褐筛,會(huì)導(dǎo)致應(yīng)用 A 可以修改應(yīng)用 B 的內(nèi)存數(shù)據(jù),這是非常不安全的
  • 內(nèi)存空間利用率低叙身,應(yīng)用對(duì)內(nèi)存的使用會(huì)出現(xiàn)內(nèi)存碎片化的問題渔扎,即使還有很多內(nèi)存可以用,但是沒有足夠的連續(xù)段的內(nèi)存分配信轿,而導(dǎo)致崩潰
  • 效率低晃痴,多個(gè)應(yīng)用同時(shí)對(duì)物理內(nèi)存進(jìn)行讀取和寫入時(shí),使用效率會(huì)非常低

為了解決上面的問題财忽,我們需要為每個(gè)應(yīng)用分配 "中間內(nèi)存" 最終會(huì)映射到物理內(nèi)存上倘核,這就是接下來(lái)要說的虛擬內(nèi)存。

操作系統(tǒng)會(huì)為每個(gè)應(yīng)用分配一個(gè)獨(dú)立的虛擬內(nèi)存即彪,實(shí)現(xiàn)應(yīng)用間的內(nèi)存隔離紧唱,避免了應(yīng)用 A 修改應(yīng)用 B 的內(nèi)存數(shù)據(jù)的問題,虛擬內(nèi)存最終會(huì)映射到物理內(nèi)存上隶校,當(dāng)應(yīng)用申請(qǐng)內(nèi)存時(shí)漏益,得到的是虛擬內(nèi)存,只有真正執(zhí)行寫操作時(shí)深胳,才會(huì)分配到物理內(nèi)存绰疤,好處是應(yīng)用可以使用連續(xù)的地址空間來(lái)訪問不連續(xù)的物理內(nèi)存。

每個(gè)應(yīng)用程序可使用的虛擬內(nèi)存大小受 CPU 位寬及內(nèi)核的限制舞终。我們常說的 16 位 cpu轻庆,32 位 cpu,64 位 CPU权埠,指的都是 CPU 的位寬榨了,表示的是一次能夠處理的數(shù)據(jù)寬度煎谍,即 CPU 能處理的 2 進(jìn)制位數(shù)攘蔽,即分別是 16bit,32bit 和 64bit呐粘。而目前市面上常用的是 32 位和 64 的設(shè)備满俗。

32 位和 64 位設(shè)備可用虛擬內(nèi)存分別是多少

32 位設(shè)備可以使用的虛擬內(nèi)存大小 3GB

32 位 CPU 架構(gòu)的設(shè)備可使用的地址空間大小為 2^32=4GB, 虛擬內(nèi)存空間分為 內(nèi)核空間用戶空間,系統(tǒng)提供了三種虛擬地址空間分配的參數(shù)作岖,代表用戶空間可訪問的虛擬地址空間大小唆垃。

  • VMSPLIT_3G : 默認(rèn)值,表示用戶空間可使用 3GB 的低地址痘儡,剩下的 1GB 高地址分配給內(nèi)核
  • VMSPLIT_2G : 表示用戶空間可使用 2GB 的低地址
  • VMSPLIT_1G : 表示用戶空間可使用 1GB 的低地址

64 位應(yīng)用可以使用的虛擬內(nèi)存大小 512GB

64 位 CPU 架構(gòu)的設(shè)備雖然擁有 64 位的地址空間辕万,但是不是全部都可以使用的,為了后期的擴(kuò)展,只能使用部分地址渐尿。

Android 默認(rèn)的虛擬地址的長(zhǎng)度配置為 CONFIG_ARM64_VA_BITS=39醉途,即 Android 的 64 位應(yīng)用可使用的地址空間大小為 2^39=512GB

當(dāng) 32 位應(yīng)用在 64 位的設(shè)備上運(yùn)行時(shí)砖茸,可使用 4GB 虛擬地址空間隘擎,而 64 位應(yīng)用可使用 512GB 的空間。因此在 64 位機(jī)器上不存在虛擬空間不足的問題凉夯。因此在 2019 年的時(shí)候 Google Play 要求除了提供 32 位的版本之外货葬,還需要提供 64 位的版本。

在我們的 OOM 崩潰設(shè)備中劲够,32 位的設(shè)備占比 50%+ 以上震桶,虛擬內(nèi)存不足主要發(fā)生在 32 位的設(shè)備上。

為什么虛擬內(nèi)存不足主要發(fā)生在 32 位的設(shè)備上

在 32 位的設(shè)備上再沧,受地址空間最大內(nèi)存 4 GB 限制尼夺,內(nèi)核空間占用 1G,剩下的 3G 是用戶空間炒瘸,我們可以通過解析 /process/pid/smaps 文件淤堵,查看當(dāng)前虛擬內(nèi)存分配情況。 android.googlesource/frameworks/…

  • 系統(tǒng)資源預(yù)分配顷扩,包含了 Zygote 進(jìn)程初始化時(shí)拐邪,需要加載 Framework 層的代碼和資源。供 Fork 出來(lái)的子進(jìn)程可以直接使用隘截。 Framework 資源包含:Framework 層 Java 代碼扎阶、so、art 虛擬機(jī)婶芭、各種靜態(tài)資源字體东臀、文件等等
  • 系統(tǒng)預(yù)分配區(qū)域中其中 [anon:libwebview reservation] 區(qū)域占用 130MB 內(nèi)存
  • App 自身資源,包括 App 中的代碼犀农、資源惰赋、 App 直接或者間接開啟線程消耗的棧空間呵哨、 App 申請(qǐng)的內(nèi)存赁濒、內(nèi)存文件映射等內(nèi)容。
  • Java 堆用于分配 Java / Kotlin 創(chuàng)建的對(duì)象孟害。由 GC 管理和回收拒炎,GC 回收時(shí)將 From Space 里的對(duì)象復(fù)制到 To Space,這兩片區(qū)域分別為 dalvik-main spacedalvik-main space 1, 這兩片區(qū)域的大小和我當(dāng)前測(cè)試機(jī) Java 堆大小一樣挨务,都是 512 MB击你,如下圖所示

根據(jù) Android 源碼中的解釋玉组,Java 堆的大小應(yīng)該是根據(jù) RAM Size 來(lái)設(shè)置的,這是一個(gè)經(jīng)驗(yàn)值丁侄,廠商是可以更改的球切,如果手機(jī) Root 之后,自己也可以改绒障,無(wú)論 RAM 多大吨凑,到目前為止 Java 堆的上限默認(rèn)都是 512MB, Google 源碼的設(shè)置如下如下圖所示户辱。

RAM (MB)-dalvik-heap. Mk heapsize (MB)
phone-hdpi-dalvik-heap. Mk 32
512-dalvik-heap. Mk 128
1024-dalvik-heap. Mk 256
2048-dalvik-heap. Mk 512
4096-dalvik-heap. Mk 512
無(wú)論 RAM 多大鸵钝,到目前為止堆的上限默認(rèn)都是 512MB
  • 內(nèi)存文件映射,mmap 是一種內(nèi)存映射文件的方法庐镐,我們的 APK恩商、Dex、so 等等都是通過 mmap 讀取的必逆,會(huì)導(dǎo)致虛擬內(nèi)存增大怠堪,mmap 占用的內(nèi)存跟讀寫有關(guān)系

經(jīng)過分析內(nèi)核、系統(tǒng)資源名眉、以及各 APP 的資源占用粟矿,最后留給我們使用的內(nèi)存并不是很多,所以我們要合理使用系統(tǒng)資源损拢,真正做到 "用時(shí)分配陌粹,及時(shí)釋放"

如何解決虛擬內(nèi)存不足的問題

目前業(yè)界也有很多黑科技來(lái)釋放因系統(tǒng)占用的虛擬內(nèi)存不足的問題福压,這些黑科技可以參考微信分享的文章 快速緩解 32 位 Android 環(huán)境下虛擬內(nèi)存地址空間不足的“黑科技”掏秩,大概有以下幾個(gè)方面的優(yōu)化。

  • Native 線程默認(rèn)的椌D罚空間大小為 1M 左右蒙幻,經(jīng)過測(cè)試大部分情況下線程內(nèi)執(zhí)行的邏輯并不需要這么大的空間,因此 Native 線程椀ㄍ玻空間減半邮破,可以減少 pthread_create OOM 崩潰
  • 系統(tǒng)預(yù)分配區(qū)域中其中 [anon:libwebview reservation] 區(qū)域占用 130MB 內(nèi)存,可以嘗試釋放 WebView 預(yù)分配的內(nèi)存腐泻,減少一部分虛擬內(nèi)存
  • 虛擬機(jī)堆空間減半决乎,在上面提到過有兩片大小相同的區(qū)域分別 dalvik-main spacedalvik-main space 1队询,虛擬機(jī)堆空間減半其實(shí)就是減少其中一個(gè) main space 所占用的內(nèi)存
  • 快手針對(duì)垃圾回收器 jemalloc 的優(yōu)化派桩,釋放的是 anon:libc_malloc 所占用的虛擬內(nèi)存 快手 Android 內(nèi)存分配器優(yōu)化探索 (一)
以下統(tǒng)計(jì)的是在 Android 7.0 App 首次啟動(dòng)完成 libc_malloc 占用的虛擬內(nèi)存 156MB

Vss         Pss             Rss             name            
159744 kB   81789 kB        82320 kB        [anon:libc_malloc]

Android 11 之前使用的垃圾回收器是 jemalloc,Android 11 之后默認(rèn)使用的垃圾回收器是 scudo蚌斩。

App 啟動(dòng)完成之后铆惑,虛擬內(nèi)存的分布

下圖是 App 在 Android 7.0 上啟動(dòng)完成之后所占用的虛擬內(nèi)存 (Vss),不同系統(tǒng)、不同的 App 虛擬內(nèi)存的分布都不一樣员魏,丑蛤,我們可以通過解析 /process/pid/smaps 文件,查看自己的 App 虛擬內(nèi)存分配情況撕阎。 android.googlesource/frameworks/…

正如上圖所示受裹,主要分為三個(gè)部分:

  • dalvik(即 Java 堆),程序在運(yùn)行過程中為對(duì)象分配內(nèi)存的區(qū)域
  • 程序文件 dex 虏束、 so 棉饶、 oat
  • Native

針對(duì)上面的問題,我們?cè)陧?xiàng)目中通過以下手段進(jìn)行優(yōu)化镇匀,重點(diǎn)優(yōu)化 dalvik 占用的內(nèi)存照藻,因篇幅問題,將會(huì)在后面的文章中汗侵,做詳細(xì)的分析:

  • Android 3.0 ~ Android 7.0 上主要將 Bitmap 對(duì)象和像素?cái)?shù)據(jù)統(tǒng)一放到 Java 堆中幸缕,Java 堆上限 512MB,而 Native 占用虛擬內(nèi)存晰韵,32 的設(shè)備可使用 3GB发乔,64 位的設(shè)備更大,因此我們可以嘗試將 Bitmap 分配到 Native 上雪猪,緩解 Java 堆的壓力列疗,降低 OOM 崩潰,方案可以參考 抖音 Android 性能優(yōu)化系列:Java OOM 優(yōu)化之 NativeBitmap 方案
  • 使用第三方圖片庫(kù)時(shí)浪蹂,需要針對(duì)高端機(jī)和低端機(jī)設(shè)置圖片庫(kù)不同的緩存大小抵栈,這樣我們?cè)诟叨藱C(jī)上保證體驗(yàn)的同時(shí),降低低端機(jī) OOM 崩潰率
  • 收斂 Bitmap坤次,避免重復(fù)創(chuàng)建 Bitmap古劲,退出界面及時(shí)釋放掉資源(Bitmap、動(dòng)畫缰猴、播放器等等資源)
  • 內(nèi)存回收兜底策略产艾,當(dāng) Activity 或者 Fragment 泄露時(shí),與之相關(guān)聯(lián)的動(dòng)畫滑绒、Bitmap闷堡、 DrawingCache 、背景疑故、監(jiān)聽器等等都無(wú)法釋放杠览,當(dāng)我們退出界面時(shí),遞歸遍歷所有的子 view纵势,釋放相關(guān)的資源踱阿,降低內(nèi)存泄露時(shí)所占用的內(nèi)存
  • 收斂線程管钳,祖?zhèn)鞔a在項(xiàng)目中有很多地方使用了 new ThreadAsyncTask 软舌、自己創(chuàng)建線程池等等操作才漆,通過統(tǒng)一的線程池等手段減少 App 創(chuàng)建線程數(shù)量,降低系統(tǒng)的開銷
  • 針對(duì)低端機(jī)和高端機(jī)采用不同的策略佛点,減少低端機(jī)內(nèi)存的占用
  • 內(nèi)存泄露是永遠(yuǎn)也解決不完的醇滥,所以需要梳理一下 Top 系列泄露問題,重點(diǎn)解決占用內(nèi)存最多的泄露超营,以及使用頻率最高的場(chǎng)景所產(chǎn)生的泄露
  • 繁創(chuàng)建小對(duì)象腺办,堆內(nèi)存累計(jì)過大,這些一般都是有明顯堆棧的糟描,根據(jù)堆棧信息解決即可怀喉。例如在循環(huán)動(dòng)畫中一直創(chuàng)建 Bitmap
  • 大對(duì)象,堆的單次分配內(nèi)存過大
  • 刪減代碼船响,減少 dex 文件占用的內(nèi)存
  • 減少 App 中 dex 數(shù)量躬拢,非必要功能,可以通過動(dòng)態(tài)下發(fā)
  • 按需加載 so 文件见间,不要提前加載所有的 so 文件聊闯,需要使用時(shí)再去加載

Java 堆上還有很多可用的內(nèi)存,為什么還會(huì)出現(xiàn) OOM

很多小伙伴們都問過我這么一個(gè)問題米诉,大概歸因了一下菱蔬,主要有以下幾個(gè)原因:

  • 內(nèi)存碎片化,沒有足夠的連續(xù)段的內(nèi)存分配
  • 虛擬內(nèi)存不足
  • 線程或者 FD 的數(shù)量超過當(dāng)前手機(jī)的閾值

文章的最后想提一點(diǎn)史侣,我們?cè)谧鲂阅軆?yōu)化的時(shí)候拴泌,不僅要關(guān)心性能指標(biāo)數(shù)據(jù),還需要關(guān)心對(duì)業(yè)務(wù)指標(biāo)數(shù)據(jù)的影響惊橱,比如對(duì)使用時(shí)長(zhǎng)蚪腐、留存等等能提升多少。

為什么需要關(guān)心業(yè)務(wù)指標(biāo)數(shù)據(jù)税朴?

性能指標(biāo)數(shù)據(jù)回季,比如 OOM 崩潰率、Native 崩潰率正林、ANR 等等泡一、可能只有客戶端的小伙伴才知道 OOM、Native觅廓、ANR 是什么意思鼻忠,但是其他人(產(chǎn)品經(jīng)理、老板等等)他們是不知道的哪亿,也不會(huì)去關(guān)心這些粥烁,但是他們對(duì)使用時(shí)長(zhǎng)、留存等業(yè)務(wù)指標(biāo)數(shù)據(jù)更加的敏感蝇棉,更能夠體現(xiàn)做這件事的價(jià)值讨阻,這只是闡述了我自己的觀點(diǎn),每個(gè)人站的角度不一樣篡殷,觀點(diǎn)也不一樣钝吮。

全文到這里就結(jié)束了,這篇文章只是梳理一下內(nèi)存相關(guān)的知識(shí)點(diǎn)板辽,以及有那些因素會(huì)導(dǎo)致 OOM 崩潰和相對(duì)應(yīng)的解決方案奇瘦。下篇文章將會(huì)介紹堆內(nèi)存堆內(nèi)存是程序在運(yùn)行過程中為對(duì)象分配內(nèi)存的區(qū)域劲弦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耳标,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子邑跪,更是在濱河造成了極大的恐慌次坡,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件画畅,死亡現(xiàn)場(chǎng)離奇詭異砸琅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)轴踱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門症脂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人淫僻,你說我怎么就攤上這事诱篷。” “怎么了雳灵?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵兴蒸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我细办,道長(zhǎng)橙凳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任笑撞,我火速辦了婚禮岛啸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茴肥。我一直安慰自己坚踩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布瓤狐。 她就那樣靜靜地躺著瞬铸,像睡著了一般批幌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗓节,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天荧缘,我揣著相機(jī)與錄音,去河邊找鬼拦宣。 笑死截粗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸵隧。 我是一名探鬼主播绸罗,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼豆瘫!你這毒婦竟也來(lái)了珊蟀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤外驱,失蹤者是張志新(化名)和其女友劉穎系洛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體略步,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡描扯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趟薄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绽诚。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杭煎,靈堂內(nèi)的尸體忽然破棺而出恩够,到底是詐尸還是另有隱情,我是刑警寧澤羡铲,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布蜂桶,位于F島的核電站,受9級(jí)特大地震影響也切,放射性物質(zhì)發(fā)生泄漏扑媚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一雷恃、第九天 我趴在偏房一處隱蔽的房頂上張望疆股。 院中可真熱鬧,春花似錦倒槐、人聲如沸旬痹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)两残。三九已至永毅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間人弓,已是汗流浹背沼死。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留票从,地道東北人漫雕。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓滨嘱,卻偏偏與公主長(zhǎng)得像峰鄙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子太雨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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