Android 性能優(yōu)化&內(nèi)存篇

本篇主要講解android內(nèi)存性能優(yōu)化之檢測方案背稼。內(nèi)存性能主要包括內(nèi)存泄漏周循, 內(nèi)存抖動, 內(nèi)存持續(xù)增長(但GC后會下降)焚挠, 內(nèi)存占用過大等問題膏萧。

Android內(nèi)存分析方向:

  • Java 內(nèi)存分析
    • Java中的內(nèi)存泄露主要特征:可達,無用
    • 無用指的是創(chuàng)建了但是不再使用之后沒有釋放
    • 能重用但是卻創(chuàng)建了新的對象進行處理
  • Native 內(nèi)存分析
    • 堆中new的對象未釋放
    • 對象引用導(dǎo)致無法釋放
  • JS 中內(nèi)存分析

本篇主要講解Java內(nèi)存分析蝌衔。

一. 日志分析

查看日志中是否有頻繁的GC榛泛。通常通過log,我們可以初步定為大部分內(nèi)存等問題噩斟。

二. 常見內(nèi)存泄漏查找

Context 泄漏, 主要為Activity 傳遞泄漏曹锨, context 未使用applciationConext 在單例創(chuàng)建時。
Handler 泄漏 , handler中持有view 剃允,context 等做耗時操作沛简。
Cursor 泄漏 , cursor未關(guān)閉
register 未 unregister
Bitmap
adapter 未使用convertView
不良代碼等

三. 命令dumpsys meminfo分析

adb shell dumpsys meminfo com.i2finance.shexpress 
Applications Memory Usage (kB):
Uptime: 142597122 Realtime: 236611715

** MEMINFO in pid 25126 [com.i2finance.shexpress] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    61111    61084        0        0    69888    64350     5537
  Dalvik Heap    49451    49316        0        0    71737    67348     4389
 Dalvik Other     3333     3332        0        0                           
        Stack      960      960        0        0                           
       Cursor       12       12        0        0                           
       Ashmem      130       88        0        0                           
      Gfx dev    23780    23780        0        0                           
    Other dev        4        0        4        0                           
     .so mmap     4373      396     3108        0                           
    .jar mmap       80        0       76        0                           
    .apk mmap    17986       64    17580        0                           
    .ttf mmap       96        0       80        0                           
    .dex mmap    15729       16    14244        0                           
    .oat mmap     2378        0      624        0                           
    .art mmap     1859     1624        8        0                           
   Other mmap     2039       12     1308        0                           
      Unknown    84240    84240        0        0                           
        TOTAL   267561   224924    37032        0   141625   131698     9926

 App Summary
                       Pss(KB)
                        ------
           Java Heap:    50948
         Native Heap:    61084
                Code:    36188
               Stack:      960
            Graphics:    23780
       Private Other:    88996
              System:     5605

               TOTAL:   267561      TOTAL SWAP (KB):        0

 Objects
               Views:      429         ViewRootImpl:        2
         AppContexts:        2           Activities:        1
              Assets:        7        AssetManagers:        3
       Local Binders:       37        Proxy Binders:       31
       Parcel memory:       26         Parcel count:       65
    Death Recipients:        2      OpenSSL Sockets:        6

 SQL
         MEMORY_USED:      567
  PAGECACHE_OVERFLOW:      157          MALLOC_SIZE:       62

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       24             45         5/24/6  /data/user/0/com.i2finance.shexpress/databases/pa_data_cache.db
         4       28             19         1/16/2  /data/user/0/com.i2finance.shexpress/databases/mpush.db
         4       60             37         5/18/6  /data/user/0/com.i2finance.shexpress/databases/fstandard.db
         4       60             91      466/22/11  /data/user/0/com.i2finance.shexpress/databases/fstandard.db (2)
         4       24             40         5/24/6  /data/user/0/com.i2finance.shexpress/databases/pa_data_cache.db

 Asset Allocations
    zip:/data/user/0/com.i2finance.shexpress/files/paanydoor_resource_3.5.0.36.jar:/resources.arsc: 67K

meminfo的信息中各字段都是什么含義齐鲤, 要理解各字段含義,我們才好進行內(nèi)存的優(yōu)化椒楣。

首先了解兩個概念:

  • 私有內(nèi)存(Dirty and Clean):
    進程獨占內(nèi)存给郊。也就是進程銷毀時可以回收的內(nèi)存容量。通常private Dirty內(nèi)存是最重要的部分撒顿,因為只被自己進程使用丑罪。Dirty內(nèi)存是已經(jīng)被修改的內(nèi)存頁,因此必須常駐內(nèi)存(因為沒有swap)凤壁;Clean內(nèi)存是已經(jīng)映射持久文件使用的內(nèi)存頁(例如正在被執(zhí)行的代碼)吩屹,因此一段時間不使用的話就可以置換出去。

  • 實際使用內(nèi)存(PSS):
    將跨進程共享頁也加入進來拧抖, 進行按比例計算PSS煤搜。這樣能夠比較準(zhǔn)確的表示進程占用的實際物理內(nèi)存。

通常我們需要關(guān)注PSS TOTALPrivate Dirty .

  • Dalvik Heap
    dalvik虛擬機分配的內(nèi)存唧席。PSS Total包含所有Zygote分配使用的內(nèi)存擦盾,共享跨進程加權(quán)。PrivateDirty 是應(yīng)用獨占內(nèi)存大小淌哟,包含獨自分配的部分和應(yīng)用進程從Zygote復(fù)制時被修改的Zygote分配的內(nèi)存頁迹卢。 HeapAlloc 是Dalvik堆和本地堆分配使用的大小,它的值比Pss Total和Private Dirty大徒仓,因為進程是從Zygote中復(fù)制分裂出來的腐碱,包含了進程共享的分配部分。
  • .so mmap & .dex mmap ... mmap 映射本地或虛擬機代碼到使用的內(nèi)存中掉弛。
  • Unknown 無法歸類的其他項症见。主要包括大部分的本地分配。
  • Native Heap native代碼申請的內(nèi)存殃饿, 堆和棧谋作,及靜態(tài)代碼塊等。
  • TOTAL進程總使用的實際內(nèi)存乎芳。
  • Objects 中顯示持有對象的個數(shù)遵蚜。這些數(shù)據(jù)也是分析內(nèi)存泄漏的重要數(shù)據(jù)。如activity等奈惑。

四. Heap Viewer

Heap Viewer 能做什么谬晕?

  • 事實查看內(nèi)存分配情況和空閑內(nèi)存大小
  • 發(fā)現(xiàn)memory Leaks

AS中點擊機器人圖標(biāo)打開Android Device Mointor, 如下:
選中進程進行Heap 分析携取,點擊update heap攒钳, 查看右側(cè)的heap標(biāo)簽頁

Paste_Image.png

Heap視圖顯示了堆內(nèi)存使用的情況,每次垃圾回收都會更新雷滋,要查看更新情況不撑, 點擊Cause GC即可文兢。
下面的內(nèi)容顯示的是分配的內(nèi)存,按照類型分類:


Paste_Image.png

如何檢查內(nèi)存泄漏

我們需要在執(zhí)行查看內(nèi)存是否有泄漏的用例之前和之后執(zhí)行GC焕檬,即手動點擊Cause GC姆坚,觀察allocated大小,查看內(nèi)存是否在一個穩(wěn)定的數(shù)值实愚,多次操作兼呵,只要內(nèi)存穩(wěn)定,即沒有內(nèi)存泄漏腊敲, 如果不斷變大击喂,即表示有內(nèi)存泄漏。
該工具也可以用來查看是否會發(fā)生內(nèi)存抖動

五. 生成Dump

分析內(nèi)存泄漏碰辅,我們需要生成相關(guān)的內(nèi)存Dump懂昂,那么我們?nèi)绾紊蒬ump文件來進行分析。

目前有兩種方式:

  • 打開Android Device Monitor
    點擊dump Hprof file


    Paste_Image.png

    會生成一份Hprof文件没宾,但該hprof文件我們無法打開凌彬,需要進行轉(zhuǎn)換之后才能用MAT工具打開弯淘,可以使用命令

hprof-conv com.i2finance.shexpress.hprof xxx.hprof 轉(zhuǎn)換生成可用的hprof文件践惑。

  • 使用Android Studio
    打開Android Studio 的Android Monitor , 選中Memory 標(biāo)簽:
    Paste_Image.png

    點擊Dump Java Heap 即可生成對應(yīng)的hprof文件籽孙,在側(cè)邊欄中打開Captures文件会钝,選中文件點擊右鍵伐蒋,export 出標(biāo)準(zhǔn)的hprof文件。
    Paste_Image.png

六. Heap Snapshot

獲取Java 堆內(nèi)存詳細信息顽素,可以分析出內(nèi)存泄漏的問題咽弦。
打開Android Studio 的Android Monitor 徒蟆, 選中Memory 標(biāo)簽胁出, 點擊Dump heap,生成hprof文件段审。AS會自動打開該文件全蝶,見下圖,但是該功能有點弱寺枉,建議還是轉(zhuǎn)換成mat可識別的hprof抑淫,使用mat進行分析。


Paste_Image.png

七. 使用LeakCanary

使用內(nèi)存檢測軟件leakCanary

  • 添加依賴包

build.gradle 中增加依賴

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
  • 開啟leakCanary

Applciationoncreate中增加語句

LeakCanary.install(this);

查看leak詳情姥闪。
當(dāng)發(fā)生內(nèi)存泄漏時始苇,會生成leak 報告, 報告中會詳細寫明具體發(fā)現(xiàn)內(nèi)存泄漏的語句筐喳。
其原理催式,可以自行上網(wǎng)搜索查看一下函喉。

八. Allocation Tracker(DeviceMonitor)

Allocation Tracker 能夠追蹤內(nèi)存分配信息, 按照順序排列荣月,這樣我們能夠清晰的看出來每一個內(nèi)存對象是怎么一步一步的分配出來的管呵。比如內(nèi)存抖動的可疑點,我們可以通過查看其內(nèi)存分配軌跡來查看段時間內(nèi)有多少相同或相似對象被創(chuàng)建哺窄,進而找到問題發(fā)生的代碼捐下。

操作步驟:

  1. 進入追蹤界面
  2. 點擊start Tracking 按鈕,開始跟蹤內(nèi)存分配軌跡
  3. 操作用例
  4. 點擊Get Allocations萌业,獲取內(nèi)存分配軌跡坷襟。


    Paste_Image.png

如上圖,上行app 從后臺切換道前臺時會調(diào)用onResume咽白,可以追蹤到最后創(chuàng)建了多個Configuration對象啤握。

上圖中,Allcated class 表示創(chuàng)建的類型晶框,第一個Allocated in 表示在哪個類中排抬, 第二個Allocated in 表示在哪個方法中。

查看源代碼如下:

public Resources getResources() {
    Resources res = super.getResources();
    Configuration config = new Configuration();
    config.setToDefaults();
    try {
        res.updateConfiguration(config, res.getDisplayMetrics());
    }catch (Exception e){
        e.printStackTrace();
    }
    return res;
}

九. Allocation Tracker(AndroidMonitor)

功能同Allocation Tracker(Andorid Device) , 但是展示更酷炫授段,更全面侵贵。
打開Android Monitor, 選中Memory 標(biāo)簽 窍育, 點擊圖標(biāo)

Paste_Image.png

卡睦, 進行內(nèi)存tracker漱抓, 再次點擊結(jié)束tracker。As會自動打開tracker文件乞娄。
下面我們詳細看一下這個面板:
Paste_Image.png

AS給我們提供了多種展示方式

  • by Method :用方法來分類我們的內(nèi)存分配
  • by Allocator : 用內(nèi)存分配器來分類我們的內(nèi)存分配
    點開每一項瞬逊,都能夠查看到方法調(diào)用棧仪或, 點擊右鍵可以跳轉(zhuǎn)到源碼。

AS 還為我們提供了統(tǒng)計蕾域,點擊餅狀圖標(biāo)按鈕即可旨巷。

分為兩種展示形式,有柱狀圖和輪胎圖契沫,分配比例可選分配次數(shù)和占用內(nèi)存大行竿颉:

  • Sunburst
    輪胎圖是以輪胎為起點,最外層是內(nèi)存實際分配的對象口予,每一個同心圓可能被分配為多個部分沪停,代表不同的子孫裳涛,每一個同心圓代表他的一個后代端三。雙擊同心圓中某一個分割部分,會變成以你點擊的那一代為圓心再向外展開妻献,如果想回到初始狀態(tài)团赁,雙擊圓心即可欢摄。
    下圖為 Sunburst + by Method


    Paste_Image.png

下圖為Sunburst + by Allocator
一個內(nèi)存的完整路徑


Paste_Image.png

比如上行的首頁中trace 的數(shù)據(jù)剧浸, 我們看下我們自己的包:

Paste_Image.png

會發(fā)現(xiàn)唆香,最外圍有很多PageScrollEvent 對象躬它, 我們?nèi)タ聪略创a:

代碼如下东涡, 我們發(fā)現(xiàn)自動loop的viewpager 每次滑動都會創(chuàng)建多個PageScorllEvent 對象。這樣也就對應(yīng)上面這幅圖了凸舵。

private class PageChangeListener implements OnPageChangeListener {
    private PageChangeListener() {
    }

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (isLoop) {
            int count = getAdapter().getCount();
            if (position < 1 || position > count - 2) {
                return;
            }
        }
        LoopViewPager.this.mEventDispatcher.dispatchEvent(new PageScrollEvent(LoopViewPager.this.getId(), SystemClock.uptimeMillis(), position, positionOffset));
    }
  • Layout
    柱狀圖是以左邊為起點失尖,從左到右的順序是某個的堆棧信息順序掀潮,縱坐標(biāo)上的寬度是以Count/Size 的大小決定的。其內(nèi)容和輪胎圖是一致的庄新。
    下圖為Layout + by Method
Paste_Image.png

十. MAT

MAT工具全稱為Memory Analyzer Tool择诈,一款詳細分析Java堆內(nèi)存的工具吭从,該工具非常強大恶迈,為了使用該工具,我們需要hprof文件.

HPROF文件存儲的是特定時間點暇仲,java進程的內(nèi)存快照奈附。有不同的格式來存儲這些數(shù)據(jù),總的來說包含了快照被觸發(fā)時java對象和類在heap中的情況将鸵。由于快照只是一瞬間的事情顶掉,所以heap dump中無法包含一個對象在何時挑胸、何地(哪個方法中)被分配這樣的信息。

幾個關(guān)鍵概念

  • Histogram:列出內(nèi)存中的對象簿透,對象的個數(shù)以及大小
  • Dominator Tree:列出最大的對象以及其依賴存活的Object (大小是以Retained Heap為標(biāo)準(zhǔn)排序的)
  • Top Consumers : 通過圖形列出最大的object
  • Duplicate Class:通過MAT自動分析泄漏的原因
  • Shallow heap : 對象本身占用內(nèi)存的大小老充,不包含其引用的對象啡浊。
    (常規(guī)對象(非數(shù)組)的Shallow size有其成員變量的數(shù)量和類型決定。數(shù)組的shallow size有數(shù)組元素的類型(對象類型蔚约、基本類型)和數(shù)組長度決定. 因為不像c++的對象本身可以存放大量內(nèi)存苹祟,java的對象成員都是些引用评雌。真正的內(nèi)存都在堆上景东,看起來是一堆原生的byte[], char[], int[],所以我們?nèi)绻豢磳ο蟊旧淼膬?nèi)存搔涝,那么數(shù)量都很小庄呈。所以我們看到Histogram圖是以Shallow size進行排序的派阱,排在第一位第二位的是byte贫母,char 。)
  • Retained Heap : 它表示如果一個對象被釋放掉绿贞,那會因為該對象的釋放而減少引用進而被釋放的所有的對象(包括被遞歸釋放的)所占用的heap大小樟蠕。
    (于是靠柑,如果一個對象的某個成員new了一大塊int數(shù)組歼冰,那這個int數(shù)組也可以計算到這個對象中。相對于shallow heap甸怕,Retained heap可以更精確的反映一個對象實際占用的大猩液肌(因為如果該對象釋放武契,retained heap都可以被釋放)荡含。)
  • outgoing references :表示該對象的出節(jié)點(被該對象引用的對象)释液。
  • incoming references :表示該對象的入節(jié)點(引用到該對象的對象)。
  • GC Root: GC發(fā)現(xiàn)通過任何reference chain(引用鏈)無法訪問某個對象的時候浸船,該對象即被回收糟袁。所以JVM就是GC Roots躺盛。
  • Unreachable指的是可以被垃圾回收器回收的對象槽惫,但是由于沒有GC發(fā)生界斜,所以沒有釋放,這時抓的內(nèi)存使用中的Unreachable就是這些對象项贺。

1. 預(yù)覽信息

打開dump 文件,通常我們需要關(guān)注一下幾個重要信息棕叫, 內(nèi)存占用餅圖俺泣,Actions部分的Histogram, Top Consumers.
我們打開Top Consumers伏钠,會生成一個報告谨设,我們可以Biggets Objects overview, 能夠看到主要內(nèi)存占用者

Paste_Image.png

點擊下面的biggest Objects 可以查看具體的地址扎拣。
還有Biggest Top Level Dominator Classes 鹏秋, 可以看到主要占用內(nèi)存的都是些什么東東侣夷。

2. dump分析

2.1 Histogram

MAT中Histogram的主要作用是查看一個instance的數(shù)量,一般用來查看自己創(chuàng)建的類的實例的個數(shù)琴锭。 可以分不同維度來查看對象的Dominator Tree視圖决帖,Group by class蓖捶、Group by class loader俊鱼、Group by package 和Histogram類似并闲,時間久了,通過多次對比也可以把溢出對象找出來溜徙。 Histogram 中可以分Group蠢壹,Thread 區(qū)分信息。 通常為:選中某一項-> show objects and class -> by incoming reference->merge shortest path to gc root -> exclude weadk reference
等流程來查看具體情況靠瞎。

可以在上面過濾相關(guān)包名,查看到具體類型制恍, 關(guān)注objects個數(shù)净神, 表示內(nèi)存dump 中有多少個相關(guān)類型對象溉委, 比如不改存在的 對象存在了瓣喊,或者有的對象內(nèi)存中有太多的份數(shù), 這樣就可以進行一個全面分析洪橘。

也可以選擇Group by package ,這樣方便根據(jù)package來進行分析熄求。


Paste_Image.png

也可以選擇thread來進行分析弟晚, 這樣查看占用內(nèi)存最多的線程指巡,這些線程可能為有內(nèi)存問題的線程隶垮。

點擊右鍵常用的幾個選項:

  • List Objects -> with incoming references 查看這個對象被哪些外部對象引用
  • List Objects-> with outcoming references 查看這個對象持有的外部對象引用
  • Path to GC Roots -> exclude ... references 查看這個對象的GC Root狸吞,不包含xxx引用,剩下的基本就是強引用了至壤。因為只有強引用一直存在像街,gc就一直無法回收該對象晋渺,從而也就出現(xiàn)內(nèi)存泄露木西。
  • Merge shortest path to GC root 找到從GC根結(jié)點到一個對象或者一組對象的共同路徑八千。從這里可以查看到對象的引用關(guān)系。
2.2 Debug Bitmap

圖片一直是內(nèi)存占用的一個大頭照皆,也是引起內(nèi)存泄露膜毁,OOM的乘睿客绰垂。所以對圖片的分析是需要非常了解劲装,這樣才能更好的優(yōu)化項目占业。*注意:圖片在內(nèi)存中占用的大星病:ARGB_8888 類型的圖片 為 內(nèi)存中圖片寬度*內(nèi)存中圖片高度4, 此處需要注意原始圖片寬高和內(nèi)存圖片寬高不一致,包括拉伸和壓縮六剥,尤其是圖片位置放錯疗疟,比如1080p設(shè)備策彤,xxxhdpi下面沒有圖片店诗,會去別的目錄下尋找圖片,此時將會對圖片拉伸必指。 **
下面我們來看一下圖片的處理。通常dump信息中圖片表現(xiàn)為兩種類型霜第,Bitmap户辞, byte[]底燎。我們需要知道該圖片是哪張圖片双仍,這樣才能好優(yōu)化相關(guān)的圖片代碼朱沃。

  • Bitmap類型
    在mat中通常能夠看到bitmap類型逗物,占用了大量的內(nèi)存,如下面這張圖片契邀,在內(nèi)存中占用2M坯门。 我們可以打開田盈,查看mBuffer變量允瞧。


    Paste_Image.png

選中mBuffer-> 右鍵選中Copy-> 選擇Save Value To File -> 生成一個xxx.data 文件述暂。

  • Byte[] 類型
    如下畦韭,查看byte的 in comming艺配, 即可看到它是一個bitmap转唉,此時如下圖,我們可以直接將該byte數(shù)據(jù)寫入xxx.data 文件麦轰。


    Paste_Image.png

下一步是選中對應(yīng)的bitmap,打開Inspector 窗口新锈,查看bitmap的尺寸茂蚓,并且使用GIMP工具(可以安裝一個聋涨,開源的)打開剛才的data文件牍白,圖像類型選擇RGB Alpha, 寬度和高度填入圖像的寬高切省,打開即可朝捆。

Paste_Image.png
Paste_Image.png
2.3 堆對比

通常為了分析內(nèi)存是否泄露,內(nèi)存是否持續(xù)增長但沒有釋放等問題儒老,我們需要dump兩次來進行內(nèi)存堆的對比记餐。

打開兩個或多個dump文件片酝,打開Navigation History視圖钠怯,點擊Historgam晦炊,選擇Add to Comp are Basket宁脊,最后選中Compare the Result 榆苞。

Paste_Image.png

在對比結(jié)果中薄疚,主要分析類型或者對象的數(shù)量是否有變化街夭, 內(nèi)存是否有變化。

通過以上手段躏筏,我們可以定位到大部分內(nèi)存問題板丽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市趁尼,隨后出現(xiàn)的幾起案子埃碱,更是在濱河造成了極大的恐慌猖辫,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砚殿,死亡現(xiàn)場離奇詭異,居然都是意外死亡似炎,警方通過查閱死者的電腦和手機荧飞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來名党,“玉大人叹阔,你說我怎么就攤上這事〈茫” “怎么了耳幢?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長欧啤。 經(jīng)常有香客問我睛藻,道長,這世上最難降的妖魔是什么邢隧? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任店印,我火速辦了婚禮,結(jié)果婚禮上倒慧,老公的妹妹穿的比我還像新娘按摘。我一直安慰自己,他們只是感情好纫谅,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布炫贤。 她就那樣靜靜地躺著,像睡著了一般付秕。 火紅的嫁衣襯著肌膚如雪兰珍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天询吴,我揣著相機與錄音掠河,去河邊找鬼。 笑死猛计,一個胖子當(dāng)著我的面吹牛唠摹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播有滑,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼跃闹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起望艺,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤苛秕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后找默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艇劫,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年惩激,在試婚紗的時候發(fā)現(xiàn)自己被綠了店煞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡风钻,死狀恐怖顷蟀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骡技,我是刑警寧澤鸣个,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站布朦,受9級特大地震影響囤萤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜是趴,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一涛舍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唆途,春花似錦富雅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滚婉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帅刀,已是汗流浹背让腹。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扣溺,地道東北人骇窍。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像锥余,于是被迫代替她去往敵國和親腹纳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

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