Android內(nèi)存管理機(jī)制和內(nèi)存泄漏分析及優(yōu)化

Android中的內(nèi)存管理機(jī)制

分配機(jī)制

Android為每個(gè)進(jìn)程分配內(nèi)存的時(shí)候,采用了彈性的分配方式郎嫁,也就是剛開始并不會(huì)一下分配很多內(nèi)存給每個(gè)進(jìn)程秉继,而是給每一個(gè)進(jìn)程分配一個(gè)“夠用”的量。這個(gè)量是根據(jù)每一個(gè)設(shè)備實(shí)際的物理內(nèi)存大小來決定的泽铛。隨著應(yīng)用的運(yùn)行尚辑,可能會(huì)發(fā)現(xiàn)當(dāng)前的內(nèi)存可能不夠使用了,這時(shí)候Android又會(huì)為每個(gè)進(jìn)程分配一些額外的內(nèi)存大小盔腔。但是這些額外的大小并不是隨意的杠茬,也是有限度的,系統(tǒng)不可能為每一個(gè)App分配無限大小的內(nèi)存弛随。

Android系統(tǒng)的宗旨是最大限度的讓更多的進(jìn)程存活在內(nèi)存中瓢喉,因?yàn)檫@樣的話,下一次用戶再啟動(dòng)應(yīng)用舀透,不需要重新創(chuàng)建進(jìn)程栓票,只需要恢復(fù)已有的進(jìn)程就可以了,減少了應(yīng)用的啟動(dòng)時(shí)間愕够,提高了用戶體驗(yàn)走贪。

回收機(jī)制

Android對(duì)內(nèi)存的使用方式是“盡最大限度的使用”,這一點(diǎn)繼承了Linux的優(yōu)點(diǎn)惑芭。Android會(huì)在內(nèi)存中保存盡可能多的數(shù)據(jù)坠狡,即使有些進(jìn)程不再使用了,但是它的數(shù)據(jù)還被存儲(chǔ)在內(nèi)存中遂跟,所以Android現(xiàn)在不推薦顯式的“退出”應(yīng)用逃沿。因?yàn)檫@樣婴渡,當(dāng)用戶下次再啟動(dòng)應(yīng)用的時(shí)候,只需要恢復(fù)當(dāng)前進(jìn)程就可以了凯亮,不需要重新創(chuàng)建進(jìn)程边臼,這樣就可以減少應(yīng)用的啟動(dòng)時(shí)間。只有當(dāng)Android系統(tǒng)發(fā)現(xiàn)內(nèi)存不夠使用触幼,需要回收內(nèi)存的時(shí)候硼瓣,Android系統(tǒng)就會(huì)需要?dú)⑺榔渌M(jìn)程,來回收足夠的內(nèi)存置谦。但是Android也不是隨便殺死一個(gè)進(jìn)程堂鲤,比如說一個(gè)正在與用戶交互的進(jìn)程,這種后果是可怕的媒峡。所以Android會(huì)有限清理那些已經(jīng)不再使用的進(jìn)程瘟栖,以保證最小的副作用。

Android殺死進(jìn)程有兩個(gè)參考條件:
進(jìn)程優(yōu)先級(jí):

Android為每一個(gè)進(jìn)程分配了優(yōu)先級(jí)的概念谅阿,優(yōu)先級(jí)越低的進(jìn)程半哟,被殺死的概率就更大。Android中總共有5個(gè)進(jìn)程優(yōu)先級(jí)签餐。具體含義這里不再給出寓涨。

  • 前臺(tái)進(jìn)程:正常不會(huì)被殺死
  • 可見進(jìn)程:正常不會(huì)被殺死
  • 服務(wù)進(jìn)程:正常不會(huì)被殺死
  • 后臺(tái)進(jìn)程:存放于一個(gè)LRU緩存列表中,先殺死處于列表尾部的進(jìn)程
  • 空進(jìn)程:正常情況下氯檐,為了平衡系統(tǒng)整體性能戒良,Android不保存這些進(jìn)程
回收收益:

當(dāng)Android系統(tǒng)開始?xì)⑺繪RU緩存中的進(jìn)程時(shí),系統(tǒng)會(huì)判斷每個(gè)進(jìn)程殺死后帶來的回收收益冠摄。因?yàn)锳ndroid總是傾向于殺死一個(gè)能回收更多內(nèi)存的進(jìn)程糯崎,從而可以殺死更少的進(jìn)程,來獲取更多的內(nèi)存河泳。殺死的進(jìn)程越少沃呢,對(duì)用戶體驗(yàn)的影響就越小。

官方推薦的App內(nèi)存使用方式
  • 當(dāng)Service完成任務(wù)后拆挥,盡量停止它薄霜。因?yàn)橛蠸ervice組件的進(jìn)程,優(yōu)先級(jí)最低也是服務(wù)進(jìn)程纸兔,這會(huì)影響到系統(tǒng)的內(nèi)存回收惰瓜。IntentService可以很好地完成這個(gè)任務(wù)。
  • 在UI不可見的時(shí)候食拜,釋放掉一些只有UI使用的資源。系統(tǒng)會(huì)根據(jù)onTrimMemory()回調(diào)方法的TRIM_MEMORY_UI_HIDDEN等級(jí)的事件副编,來通知App UI已經(jīng)隱藏了负甸。這和onStop()方法還是有很大區(qū)別的,因?yàn)閛nStop()方法只是當(dāng)一個(gè)Activity完全不可見的時(shí)候就會(huì)調(diào)用,比如說用戶打開了我們程序中的另一個(gè)Activity呻待。因此打月,我們可以在onStop()方法中去釋放一些Activity相關(guān)的資源,比如說取消網(wǎng)絡(luò)連接或者注銷廣播接收器等蚕捉,但是UI相關(guān)的資源等onTrimMemory(TRIM_MEMORY_UI_HIDDEN)這個(gè)回調(diào)之后才去釋放奏篙,這樣可以保證如果用戶只是從我們程序的一個(gè)Activity回到了另外一個(gè)Activity,界面相關(guān)的資源都不需要重新加載迫淹,從而提升響應(yīng)速度秘通。
@Override  
public void onTrimMemory(int level) {  
    super.onTrimMemory(level);  
    switch (level) {  
    case TRIM_MEMORY_UI_HIDDEN:  
        // 進(jìn)行資源釋放操作  
        break;  
    }  
}  
  • 在系統(tǒng)內(nèi)存緊張的時(shí)候,盡可能多的釋放掉一些非重要資源敛熬。系統(tǒng)會(huì)根據(jù)onTrimMemory()回調(diào)方法來通知內(nèi)存緊張的狀態(tài)肺稀,App應(yīng)該根據(jù)不同的內(nèi)存緊張等級(jí),來合理的釋放資源应民,以保證系統(tǒng)能夠回收更多內(nèi)存话原。當(dāng)系統(tǒng)回收到足夠多的內(nèi)存時(shí),就不用殺死進(jìn)程了诲锹。
  • 檢查自己最大可用的內(nèi)存大小繁仁。這對(duì)一些緩存框架很有用,因?yàn)檎G闆r下归园,緩存框架的緩存池大小應(yīng)當(dāng)指定為最大內(nèi)存的百分比黄虱,這樣才能更好地適配更多的設(shè)備。通過getMemoryClass()和getLargeMemoryClass()來獲取可用內(nèi)存大小的信息蔓倍。
  • 避免濫用Bitmap導(dǎo)致的內(nèi)存浪費(fèi)悬钳。
    根據(jù)當(dāng)前設(shè)備的分辨率來壓縮Bitmap是一個(gè)不錯(cuò)的選擇,在使用完Bitmap后偶翅,記得要使用recycle()來釋放掉Bitmap默勾。使用軟引用或者弱引用來引用一個(gè)Bitmap,使用LRU緩存來對(duì)Bitmap進(jìn)行緩存聚谁。
  • 使用針對(duì)內(nèi)存優(yōu)化過的數(shù)據(jù)容器母剥。針對(duì)移動(dòng)設(shè)備內(nèi)存有限的問題,Android提供了一套針對(duì)內(nèi)存優(yōu)化過的數(shù)據(jù)容器形导,來替代JDK原生提供的數(shù)據(jù)容器环疼。但是缺點(diǎn)就是,時(shí)間復(fù)雜度被提高了朵耕。比如SparseArray炫隶、SparseBooleanArray、LongSparseArray阎曹、
  • 意識(shí)到內(nèi)存的過度消耗伪阶。Enum類型占用的內(nèi)存是常量的兩倍多煞檩,所以避免使用enum,直接使用常量栅贴。
    每一個(gè)Java的類(包括匿名內(nèi)部類)都需要500Byte的代碼斟湃。每一個(gè)類的實(shí)例都有12-16 Byte的額外內(nèi)存消耗。注意類似于HashMap這種檐薯,內(nèi)部還需要生成Class的數(shù)據(jù)容器凝赛,這會(huì)消耗更多內(nèi)存。
  • 抽象代碼也會(huì)帶來更多的內(nèi)存消耗坛缕。如果你的“抽象”設(shè)計(jì)實(shí)際上并沒有帶來多大好處墓猎,那么就不要使用它。
  • 使用nano protobufs 來序列化數(shù)據(jù)祷膳。Google設(shè)計(jì)的一個(gè)語(yǔ)言和平臺(tái)中立打的序列化協(xié)議陶衅,比XML更快、更小直晨、更簡(jiǎn)單搀军。
  • 避免使用依賴注入的框架。依賴注入的框架需要開啟額外的服務(wù)勇皇,來掃描App中代碼的Annotation罩句,所以需要額外的系統(tǒng)資源。
  • 使用ZIP對(duì)齊的APK敛摘。對(duì)APK做Zip對(duì)齊门烂,會(huì)壓縮其內(nèi)部的資源,運(yùn)行時(shí)會(huì)占用更少的內(nèi)存兄淫。
  • 合理使用多進(jìn)程屯远。

Android內(nèi)存泄漏分析及優(yōu)化

內(nèi)存泄漏的根本原因
內(nèi)存泄漏分析1.png

如上圖所示,GC會(huì)選擇一些它了解還存活的對(duì)象作為內(nèi)存遍歷的根節(jié)點(diǎn)(GC Roots)捕虽,比方說thread stack中的變量慨丐,JNI中的全局變量,zygote中的對(duì)象(class loader加載)等泄私,然后開始對(duì)heap進(jìn)行遍歷房揭。到最后,部分沒有直接或者間接引用到GC Roots的就是需要回收的垃圾晌端,會(huì)被GC回收掉捅暴。如下圖藍(lán)色部分。

內(nèi)存泄漏分析2.png

內(nèi)存泄漏指的是進(jìn)程中某些對(duì)象(垃圾對(duì)象)已經(jīng)沒有使用價(jià)值了咧纠,但是它們卻可以直接或間接地引用到gc roots導(dǎo)致無法被GC回收蓬痒。無用的對(duì)象占據(jù)著內(nèi)存空間,使得實(shí)際可使用內(nèi)存變小漆羔,形象地說法就是內(nèi)存泄漏了梧奢。下面分析一些可能導(dǎo)致內(nèi)存泄漏的情景瞪讼。

Android中常見的內(nèi)存泄漏原因

1.使用static變量引起的內(nèi)存泄漏

因?yàn)閟tatic變量的生命周期是在類加載時(shí)開始 類卸載時(shí)結(jié)束,也就是說static變量是在程序進(jìn)程死亡時(shí)才釋放粹断,如果在static變量中引用了Activity那么這個(gè)Activity由于被引用,便會(huì)隨static變量的生命周期一樣嫡霞,一直無法被釋放瓶埋,造成內(nèi)存泄漏。

一般解決辦法:
想要避免context相關(guān)的內(nèi)存泄漏诊沪,需要注意以下幾點(diǎn):

  • 不要對(duì)activity的context長(zhǎng)期引用(一個(gè)activity的引用的生存周期應(yīng)該和activity的生命周期相同)
  • 如果可以的話养筒,盡量使用關(guān)于application的context來替代和activity相關(guān)的context
  • 如果一個(gè)acitivity的非靜態(tài)內(nèi)部類的生命周期不受控制,那么避免使用它端姚;正確的方法是使用一個(gè)靜態(tài)的內(nèi)部類晕粪,并且對(duì)它的外部類有一WeakReference,就像在ViewRootImpl中內(nèi)部類W所做的那樣,使用弱引用private final WeakReference<ViewRootImpl> mViewAncestor;渐裸。

下面的代碼存在內(nèi)存泄漏的問題巫湘,非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例導(dǎo)致內(nèi)存泄漏。

/**
mDemo會(huì)獲得并一直持有MemoryLeakActivity的引用昏鹃。當(dāng)MemoryLeakActivity銷毀后重建尚氛,因?yàn)閙Demo持有引用,無法被GC回收的洞渤,進(jìn)程中會(huì)存在2個(gè)MemoryLeakActivity實(shí)例阅嘶。所以,對(duì)于lauchMode不是singleInstance的Activity载迄, 應(yīng)該避免在activity里面實(shí)例化其非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例讯柔。
*/
public class MemoryLeakActivity extends AppCompatActivity{
    private TextView view;
    private static final String TAG = "MemoryLeakActivity";
    static Demo mDemo;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new TextView(MemoryLeakActivity.this);
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        view.setText("啟動(dòng)一個(gè)持有本對(duì)象的線程");
        view.setTextSize(40);
        view.setTextColor(Color.parseColor("#0000ff"));
        setContentView(view);
        mDemo = new Demo();
        mDemo.run();
    }
    class Demo{
        void run(){
            Log.i(TAG, "run: ");
        }
    }
}

解決方法:將Demo改成靜態(tài)內(nèi)部類

因?yàn)槠胀ǖ膬?nèi)部類對(duì)象隱含地保存了一個(gè)引用,指向創(chuàng)建它的外圍類對(duì)象护昧。然而魂迄,當(dāng)內(nèi)部類是static的時(shí),就不是這樣了捏卓。嵌套類意味著: 1. 嵌套類的對(duì)象极祸,并不需要其外圍類的對(duì)象。 2. 不能從嵌套類的對(duì)象中訪問非靜態(tài)的外圍類對(duì)象怠晴。

2.線程引起的內(nèi)存泄漏

下面的代碼存在內(nèi)存泄漏的問題遥金,啟動(dòng)線程的匿名內(nèi)部類會(huì)持有MemoryLeakActivity.this的引用。如果線程還沒有結(jié)束蒜田,Activity已經(jīng)銷毀那就會(huì)造成內(nèi)存泄漏稿械。

public class MemoryLeakActivity extends AppCompatActivity{
    private TextView view;
    private static final String TAG = "MemoryLeakActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new TextView(MemoryLeakActivity.this);
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        view.setText("啟動(dòng)一個(gè)持有本對(duì)象的線程");
        view.setTextSize(40);
        view.setTextColor(Color.parseColor("#0000ff"));
        setContentView(view);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(8000000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(runnable).start();
    }
}

解決辦法:
1.合理安排線程執(zhí)行的時(shí)間,控制線程在Activity結(jié)束前結(jié)束冲粤。
2.將內(nèi)部類改為靜態(tài)內(nèi)部類美莫,并使用弱引用WeakReference來保存Activity實(shí)例 因?yàn)槿跻?只要GC發(fā)現(xiàn)了 就會(huì)回收它 页眯,因此可盡快回收。

將匿名內(nèi)部類改成靜態(tài)類厢呵,避免了Activity context的內(nèi)存泄漏問題

/**
 * 示例通過將線程類聲明為私有的靜態(tài)內(nèi)部類避免了 Activity context 的內(nèi)存泄漏問題窝撵,但
 * 在配置發(fā)生改變后,線程仍然會(huì)執(zhí)行襟铭。原因在于碌奉,DVM 虛擬機(jī)持有所有運(yùn)行線程的引用,無論
 * 這些線程是否被回收寒砖,都與 Activity 的生命周期無關(guān)赐劣。運(yùn)行中的線程只會(huì)繼續(xù)運(yùn)行,直到
 * Android 系統(tǒng)將整個(gè)應(yīng)用進(jìn)程殺死
*/
public class MemoryLeakActivity extends AppCompatActivity{
    private TextView view;
    private static final String TAG = "MemoryLeakActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new TextView(MemoryLeakActivity.this);
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        view.setText("啟動(dòng)一個(gè)持有本對(duì)象的線程");
        view.setTextSize(40);
        view.setTextColor(Color.parseColor("#0000ff"));
        setContentView(view);
        new MyThread().start();
    }

    private static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                Thread.sleep(8000000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } 
        }
    }
}

在Activity生命周期的onDestory中結(jié)束線程運(yùn)行

/**
* 除了我們需要實(shí)現(xiàn)銷毀邏輯以保證線程不會(huì)發(fā)生內(nèi)存泄漏哩都。在退出當(dāng)前
* Activity 前使用 onDestroy() 方法結(jié)束你的運(yùn)行中線程魁兼。
*/
public class MemoryLeakActivity extends AppCompatActivity{
    private TextView view;
    private static final String TAG = "MemoryLeakActivity";
    private static boolean mRunnale = false;
    private MyThread mThread; 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new TextView(MemoryLeakActivity.this);
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        view.setText("啟動(dòng)一個(gè)持有本對(duì)象的線程");
        view.setTextSize(40);
        view.setTextColor(Color.parseColor("#0000ff"));
        setContentView(view);
        new MyThread().start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mThread.closeThread();
    }

    private static class MyThread extends Thread{
        @Override
        public void run() {
            mRunnale = true;
            while (true){
                //TODO
                Log.i(TAG, "run: do something");
            }
        }
        
        public void closeThread(){
            mRunnale = false;
        }
    }
}

3.Handler的使用造成的內(nèi)存泄漏

由于在Handler的使用中,handler會(huì)發(fā)送message對(duì)象到 MessageQueue中 然后 Looper會(huì)輪詢MessageQueue 然后取出Message執(zhí)行漠嵌,但是如果一個(gè)Message長(zhǎng)時(shí)間沒被取出執(zhí)行咐汞,那么由于 Message中有 Handler的引用,而 Handler 一般來說也是內(nèi)部類對(duì)象儒鹿,Message引用 Handler 碉考,Handler引用 Activity 這樣 使得 Activity無法回收⊥ι恚或者說Handler在Activity退出時(shí)依然還有消息需要處理侯谁,那么這個(gè)Activity就不會(huì)被回收。

解決辦法:
依舊使用 靜態(tài)內(nèi)部類+弱引用的方式 可解決
例如下面的代碼

public class MemoryLeakActivity extends AppCompatActivity{
    private TextView view;
    private static final String TAG = "MemoryLeakActivity";
    private MyHandler mHandler;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new TextView(MemoryLeakActivity.this);
        view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        view.setText("啟動(dòng)一個(gè)持有本對(duì)象的線程");
        view.setTextSize(40);
        view.setTextColor(Color.parseColor("#0000ff"));
        setContentView(view);
        mHandler = new MyHandler(this);
        mHandler.sendEmptyMessage(0);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //第三步章钾,在Activity退出的時(shí)候移除回調(diào)
        mHandler.removeCallbacksAndMessages(null);
    }

    //第一步墙贱,將Handler改成靜態(tài)內(nèi)部類。
    static class MyHandler extends Handler{
        //第二步贱傀,將需要引用Activity的地方惨撇,改成弱引用。
        private WeakReference<MemoryLeakActivity> mActivityRef;
        public MyHandler(MemoryLeakActivity activity){
            mActivityRef = new WeakReference<MemoryLeakActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MemoryLeakActivity mla = mActivityRef == null ? null : mActivityRef.get();
            if(mla == null || mla.isFinishing()){
                return;
            }
            //TODO
            mla.view.setText("do something");

        }
    }
}

4.資源未被及時(shí)關(guān)閉造成的內(nèi)存泄漏

比如一些Cursor 沒有及時(shí)close 會(huì)保存有Activity的引用府寒,導(dǎo)致內(nèi)存泄漏

解決辦法:
在onDestory方法中及時(shí) close即可

5.BitMap占用過多內(nèi)存

bitmap的解析需要占用內(nèi)存魁衙,但是內(nèi)存只提供8M的空間給BitMap,如果圖片過多株搔,并且沒有及時(shí) recycle bitmap 那么就會(huì)造成內(nèi)存溢出剖淀。

解決辦法:
及時(shí)recycle 壓縮圖片之后加載圖片

其中還有一些關(guān)于 集合對(duì)象沒移除,注冊(cè)的對(duì)象沒反注冊(cè)纤房,代碼壓力的問題也可能產(chǎn)生內(nèi)存泄漏纵隔,但是使用上述的幾種解決辦法一般都是可以解決的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捌刮,隨后出現(xiàn)的幾起案子碰煌,更是在濱河造成了極大的恐慌,老刑警劉巖绅作,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芦圾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡俄认,警方通過查閱死者的電腦和手機(jī)堕扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梭依,“玉大人,你說我怎么就攤上這事典尾∫鬯” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵钾埂,是天一觀的道長(zhǎng)河闰。 經(jīng)常有香客問我,道長(zhǎng)褥紫,這世上最難降的妖魔是什么姜性? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮髓考,結(jié)果婚禮上部念,老公的妹妹穿的比我還像新娘。我一直安慰自己氨菇,他們只是感情好儡炼,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著查蓉,像睡著了一般乌询。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豌研,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天妹田,我揣著相機(jī)與錄音,去河邊找鬼鹃共。 笑死鬼佣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的霜浴。 我是一名探鬼主播沮趣,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼坷随!你這毒婦竟也來了房铭?” 一聲冷哼從身側(cè)響起驻龟,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缸匪,沒想到半個(gè)月后翁狐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凌蔬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年露懒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砂心。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡懈词,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辩诞,到底是詐尸還是另有隱情坎弯,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布译暂,位于F島的核電站抠忘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏外永。R本人自食惡果不足惜崎脉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伯顶。 院中可真熱鬧囚灼,春花似錦、人聲如沸祭衩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汪厨。三九已至赃春,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劫乱,已是汗流浹背织中。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衷戈,地道東北人狭吼。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像殖妇,于是被迫代替她去往敵國(guó)和親刁笙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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