Android常見的內(nèi)存泄露場(chǎng)景

心情么么噠,又可以白嫖咯...

常見概念

  1. 什么是內(nèi)存泄露?

    該被GC回收的內(nèi)存沒有被回收。講人話:短生命周期的引用被長生命周期的對(duì)象持有释涛,導(dǎo)致短生命周期的對(duì)象的內(nèi)存無法被GC回收。舉個(gè)例子:非靜態(tài)內(nèi)部類默認(rèn)持有外部類的引用倦沧,不幸的是唇撬,我們?cè)谕獠款悇?chuàng)建了一個(gè)該內(nèi)部類的靜態(tài)實(shí)例。靜態(tài)實(shí)例的生命周期與長與普通實(shí)例的生命周期展融,而靜態(tài)實(shí)例是可以作為GCRoots的根節(jié)點(diǎn)的窖认,導(dǎo)致GC在進(jìn)行可達(dá)性分析時(shí),外部類的引用一直在引用鏈上告希,不被回收扑浸。這樣就導(dǎo)致了外部類對(duì)象的內(nèi)存泄露。

    持續(xù)的內(nèi)存泄露會(huì)導(dǎo)致內(nèi)存溢出

  2. 什么是內(nèi)存溢出燕偶?

    ** 程序申請(qǐng)內(nèi)存時(shí)喝噪,內(nèi)存空間沒有足夠的內(nèi)存分配,就會(huì)導(dǎo)致內(nèi)存溢出**指么。類比生活中的例子:假設(shè)你朋友租的房子不大酝惧,且他不注意衛(wèi)生榴鼎,每次消費(fèi)完(喝小酒,擼個(gè)串...)都不打掃衛(wèi)生晚唇,一天兩天還好巫财,時(shí)間長了...呵呵,反正房子就那么大缺亮,垃圾多了翁涤,躺個(gè)地都沒了桥言。

    Android中出現(xiàn)內(nèi)存溢出萌踱,是一件大事,因?yàn)槟愕膽?yīng)用會(huì)被強(qiáng)制退出号阿。

  3. 什么是內(nèi)存抖動(dòng)并鸵?

    短時(shí)間內(nèi)有大量的對(duì)象被創(chuàng)建和回收。類比生活中的正弦函數(shù)扔涧,在半個(gè)周期內(nèi)园担,我們不斷的創(chuàng)建對(duì)象,申請(qǐng)內(nèi)存枯夜,很快就攀到了波峰弯汰,接著出現(xiàn)了GC(Stop The World),清理內(nèi)存湖雹,幾乎一瞬間就到了起步線咏闪。這樣一個(gè)急上急下的折線圖,就是內(nèi)存抖動(dòng)的表現(xiàn)摔吏。

    Android的UI卡頓就是內(nèi)存抖動(dòng)導(dǎo)致鸽嫂,移步了解UI卡頓與內(nèi)存抖動(dòng)的前世今生

Android 的虛擬機(jī)是基于寄存器的Dalvik/ART,它的最大堆大小一般是16M,但是根據(jù)不同的ROM征讲,這個(gè)最大值有可能不一樣据某。如果我們占用的內(nèi)存超出ROM給出的最大值,那么一定會(huì)出現(xiàn)OOM诗箍。

Java內(nèi)存分配策略

Java程序運(yùn)行時(shí)的內(nèi)存分配策略有三種癣籽,分別是靜態(tài)分配,棧式分配和堆式分配滤祖,對(duì)應(yīng)的這三種存儲(chǔ)策略使用的內(nèi)存空間主要分別是靜態(tài)存儲(chǔ)區(qū)(也稱方法區(qū))筷狼、棧區(qū)和堆區(qū)。

  • 靜態(tài)存儲(chǔ)區(qū)(方法區(qū)):存放靜態(tài)數(shù)據(jù)氨距,全局static數(shù)據(jù)和常量桑逝,生命周期最長,即程序啥時(shí)候退出我啥時(shí)候讓出來內(nèi)存俏让。
  • 棧區(qū):當(dāng)方法被執(zhí)行時(shí)楞遏,方法體內(nèi)的局部變量(其中包括基礎(chǔ)數(shù)據(jù)類型茬暇,對(duì)象引用)都在棧上創(chuàng)建,并在方法執(zhí)行結(jié)束時(shí)這些局部變量所持有的內(nèi)存將會(huì)自動(dòng)被釋放寡喝,因?yàn)闂?nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中糙俗,效率很高,但是分配的內(nèi)存容量有限预鬓。
  • 堆區(qū):通常就是指在程序運(yùn)行時(shí)直接new出來的內(nèi)存巧骚,也就是對(duì)象的實(shí)例,這部分內(nèi)存在不使用時(shí)將由GC來負(fù)責(zé)回收格二。

棧與堆的區(qū)別

在方法體內(nèi)定義的(局部變量)一些基本類型的變量和對(duì)象的引用變量都在棧內(nèi)存中分配的劈彪,當(dāng)在一個(gè)方法體中定義一個(gè)變量時(shí),Java就會(huì)在棧中為該變量的引用分配內(nèi)存空間顶猜,當(dāng)方法退出沧奴,該變量也就無效了,分配給她的內(nèi)存空間也將被釋放长窄,該內(nèi)存空間可以被重新使用滔吠。

堆內(nèi)存用來存放所有由new 創(chuàng)建的對(duì)象(包括對(duì)象其中的所有成員變量)和數(shù)組,在堆中分配的內(nèi)存挠日,將由GC來自動(dòng)管理疮绷,在堆中產(chǎn)生一個(gè)數(shù)據(jù)或?qū)ο蠛螅€可以在棧中定義一個(gè)特殊變量嚣潜,這個(gè)變量的取值等于數(shù)據(jù)或者對(duì)象在內(nèi)存中的首地址冬骚,這個(gè)特殊的變量就是我們上面說的引用變量,我們可以通過這個(gè)引用變量來訪問堆中的對(duì)象或者數(shù)組郑原。

    public class Sample {
        int s1 = 0;
        Sample mSample1 = new Sample();
        public void method() {
            int s2 = 1;
            Sample mSample2 = new Sample();
        }
    }
    Sample mSample3 = new Sample();

Sample類的局部變量s2和引用變量mSample2都是存放在棧中的唉韭,但mSample2指向的對(duì)象是存放在堆上的,mSample3指向的對(duì)象實(shí)體也存放在堆上犯犁,包括這個(gè)對(duì)象的所有成員變量s1和mSample1属愤。注意:當(dāng)方法退出后,mSample2引用在棧中的內(nèi)存會(huì)被回收酸役,它指向的堆內(nèi)存上的對(duì)象需要等GC來回收住诸。

總結(jié):

局部變量的基本數(shù)據(jù)類型和引用存儲(chǔ)于棧中,引用的對(duì)象實(shí)體存在于堆中涣澡,因?yàn)樗麄儗儆诜椒ㄖ械淖兞考牛芷陔S著方法而結(jié)束

成員變量全部存儲(chǔ)于堆中(包括基本數(shù)據(jù)類型,引用和引用對(duì)象的實(shí)體)入桂,因?yàn)樗麄儗儆陬愌俎保悓?duì)象終究是要被new出來使用的。

Java是如何管理內(nèi)存的

Java內(nèi)存管理解決了對(duì)象的分配和釋放問題抗愁。在Java中馁蒂,我們只需要通過關(guān)鍵字new為每個(gè)對(duì)象申請(qǐng)內(nèi)存空間(基本類型除外)呵晚,所有的對(duì)象都在堆(heap)中分配空間,另外對(duì)象的釋放是由GC決定和執(zhí)行的沫屡。這種分工饵隙,方便了我們,卻加重了JVM的工作沮脖,因?yàn)榍謇砝墓ぷ魇呛芟腃PU的金矛。

Java是如何精確判斷哪些內(nèi)存需要釋放的?大家請(qǐng)移步至該文章可達(dá)性分析與計(jì)數(shù)器

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

  1. 集合類泄漏

    如果我們僅僅調(diào)用集合類的添加方法勺届,而沒有執(zhí)行相應(yīng)的刪除驶俊,且這個(gè)集合類的引用是個(gè)類變量(比如說類中的靜態(tài)屬性,全局性的map等涮因,即有靜態(tài)引用或final一直指向它)废睦,那么集合中的元素的對(duì)象占用的內(nèi)存就會(huì)泄露伺绽。

  2. 單例造成的內(nèi)存泄漏

    由于單例的靜態(tài)特性使得其生命周期跟應(yīng)用的生命周期一樣長养泡,所以如果使用不恰當(dāng),很容易造成內(nèi)存泄漏奈应,比如說下面一個(gè)典型的例子

        public class AppManager {
            private static AppManager instance;
            private Context context;
            private AppManager(Context context) {
                this.context = context;
            }
            public static AppManager getInstance(Context context) {
                if (instance == null) {
                    instance = new AppManager(context);
                }
                return instance;
            }
        }
        
    
    1. 如果此時(shí)傳入的是Application的Context澜掩,因?yàn)锳pplication的生命周期就是整個(gè)應(yīng)用的生命周期,所以這將沒沒有任何問題杖挣。

    2. 如果此時(shí)傳入的是Activity的Context肩榕,當(dāng)這個(gè)Context所對(duì)應(yīng)的Activity退出時(shí),由于該Context的引用被單例對(duì)象所持有惩妇,其生命周期等于整個(gè)應(yīng)用程序的生命周期株汉,所以當(dāng)Activity退出時(shí)它的內(nèi)存并不會(huì)被回收,這就造成了內(nèi)存泄漏歌殃。

  3. 靜態(tài)全局變量

    public class MyActivity extends Activity {
        
        private static Drawable sBackground;
        
        @override
        protect void onCreate(Bundle state) {
            super.onCreate(state);
            TextView table = new TextView(this);
            table.setText("title");
            if(sBackground == null) {
                sBackground = getDrawable();
            }
            table.setBackgroundDrwable(sBackground);
            setContentView(table);
        }
    }
    
    

    sBackground 是一個(gè)靜態(tài)全局變量乔妈,它的生命周期跟隨類實(shí)例而不是對(duì)象實(shí)例,因此它會(huì)在應(yīng)用退出后后才消失氓皱。而此時(shí)路召,我們將drawable與TextView結(jié)合,而TextView含有當(dāng)前 this 的引用波材,所以該 activity 的實(shí)例依然在內(nèi)存中股淡,引用鏈如下:sBackground -> table -> this。
    我們知道GC是不會(huì)回收存在引用鏈的對(duì)象的廷区,所以 activity實(shí)例占用的內(nèi)存不會(huì)被回收唯灵。

  4. 內(nèi)部類(非靜態(tài)內(nèi)部類和匿名內(nèi)部類)

    非靜態(tài)內(nèi)部類創(chuàng)建靜態(tài)實(shí)例造成的內(nèi)存泄漏

         public class MainActivity extends AppCompatActivity {
            private static TestResource mResource = null;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                if(mManager == null){
                    mManager = new TestResource();
                }
                //...
            }
            class TestResource {
            //...
            }
         }
    

    在Activity內(nèi)部創(chuàng)建一個(gè)非靜態(tài)內(nèi)部類的單例對(duì)象,每次啟動(dòng)Activity時(shí)都會(huì)使用該單例的數(shù)據(jù)隙轻。這樣雖然避免了資源的重復(fù)創(chuàng)建埠帕,不過這種寫法卻會(huì)造成內(nèi)存泄漏忌傻,因?yàn)榉庆o態(tài)內(nèi)部類默認(rèn)會(huì)持有外部類的引用,而該非靜態(tài)內(nèi)部類又創(chuàng)建了一個(gè)靜態(tài)的實(shí)例搞监,該實(shí)例的生命周期和應(yīng)用的一樣長水孩,這就導(dǎo)致了該靜態(tài)實(shí)例一直會(huì)持有該Activity的引用,導(dǎo)致Activity的內(nèi)存資源不能正乘雎浚回收俘种。如何修正那?

    將該內(nèi)部類設(shè)置為靜態(tài)內(nèi)部類或?qū)⒃搩?nèi)部類抽取出來封裝成一個(gè)單例绝淡,如果需要使用Context宙刘,請(qǐng)使用Application的Context,當(dāng)然Application的Context不是萬能的所以也不能隨便亂用牢酵,對(duì)于有些地方則必須使用Activity的Context悬包。對(duì)于Application,Service馍乙,Activity的三者的Context的應(yīng)用場(chǎng)景如下:

    image

    其中 NO1表示Application和Service可以啟動(dòng)一個(gè)Activity布近,不過需要?jiǎng)?chuàng)建一個(gè)新的task任務(wù)隊(duì)列,而對(duì)于Dialog而言只有在Activity中才能創(chuàng)建丝格。

    匿名內(nèi)部類

    Android開發(fā)過程中撑瞧,如果在Activity/Fragment/View中,使用了匿名內(nèi)部類显蝌,并被異步線程持有了预伺,那就要小心了,如果沒有任何防護(hù)措施曼尊,一定會(huì)導(dǎo)致泄漏酬诀。

    public class MainActivity extends Activity {
        ...
        Runnable ref1 = new MyRunable();
        Runnable ref2 = new Runnable() {
            @Override
            public void run() {
    
            }
        };
        ...
    }
    

    ref1和ref2的區(qū)別是,ref2使用了匿名內(nèi)部類骆撇,我們來看看運(yùn)行時(shí)這兩個(gè)引用的內(nèi)存


    image

    可以看到瞒御,ref2這個(gè)匿名類的實(shí)現(xiàn)對(duì)象里面多了一個(gè)引用,這個(gè)引用指向MainActivity.this艾船,也就是說當(dāng)前的MainActivity實(shí)例會(huì)被ref2持有葵腹,如果這個(gè)引用再傳入一個(gè)異步線程,且線程的生命周期此Activity生命周期長的時(shí)候(發(fā)出了一個(gè)復(fù)雜的I/O請(qǐng)求)屿岂,就會(huì)造成內(nèi)存泄漏践宴。如何解決這類問題那?
    新建一個(gè)靜態(tài)內(nèi)部類爷怀。但是有一個(gè)問題還需要注意:如果在 run()中阻肩,使用了activity里面的資源,一定要判空哦。

  5. Handler造成的內(nèi)存泄漏

    Handler的使用造成的內(nèi)存泄漏問題應(yīng)該說是最為常見的烤惊,很多時(shí)候我們?yōu)榱吮苊釧NR而不再主線程中進(jìn)行耗時(shí)操作乔煞,在處理網(wǎng)絡(luò)任務(wù)或者封裝一些請(qǐng)求回調(diào)等API都借助Handler來處理。
    注意:Handler不是萬能的柒室,對(duì)于Handler的使用渡贾,一不小心就有可能造成內(nèi)存泄漏。為什么那?
    舉個(gè)例子:請(qǐng)看下面的代碼

    public class SampleActivity extends Activity {
        private final Handler mLeakyHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // ...
            }
        }
        private final Handler secondHandler = new Handler();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Post a message and delay its execution for 10 minutes.
            mLeakyHandler.sendMessageAtTime(2*1000*60)
            secondHandler.postRunnable({
            }, 1000*60*2)
    
            // Go back to the previous Activity.
            finish();
        }
    }
    

    首先我們知道:Android中的 main線程只有在應(yīng)用退出的時(shí)候才退出⌒塾遥現(xiàn)在我們?cè)贏ctivity中聲明一個(gè)handler空骚,使用它發(fā)送一個(gè)一個(gè)延遲2分鐘執(zhí)行的消息。當(dāng)該Activity被finish掉時(shí)擂仍,我們也沒有將該消息從MessgaeQueue中移除囤屹,那么這個(gè)消息還會(huì)繼續(xù)存在于主線程的MessageQueue中。第一個(gè)handler我們使用了匿名內(nèi)部類的方式創(chuàng)建了handler逢渔,導(dǎo)致它持有了該Activity實(shí)例的引用肋坚,所以此時(shí)finish掉的Activity就不會(huì)被回收,從而導(dǎo)致造成activity的內(nèi)存泄漏肃廓;第二個(gè)handler雖然沒有使用匿名內(nèi)部類方式創(chuàng)建智厌,但是它發(fā)送了一個(gè)runnable消息,而runnable是匿名內(nèi)部類亿昏,所以峦剔,它也會(huì)造成內(nèi)存泄露。
    解決這類內(nèi)存泄露的方法:在onStop的時(shí)候從MessageQueue中移出去吧角钩。

  6. Bitmap導(dǎo)致的內(nèi)存泄露

    在Java中對(duì)象的引用類型分為四種:


    image

    在Android應(yīng)用的開發(fā)中,為了防止內(nèi)存溢出呻澜,在處理一些占用大量而且生命周期比較長的對(duì)象時(shí)候递礼,可以進(jìn)來應(yīng)用軟引用和弱引用技術(shù)。

    軟引用羹幸、弱引用和一個(gè)引用隊(duì)列聯(lián)合使用脊髓,如果軟引用所引用的對(duì)象被垃圾回收器回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中栅受,利用這個(gè)隊(duì)列可以得知被回收的軟/弱引用的對(duì)象列表将硝,從而為緩沖器清除已失效的軟/弱引用。

    假設(shè)我們的應(yīng)用會(huì)用到大量的默認(rèn)圖片屏镊,比如應(yīng)用中有默認(rèn)的頭像依疼,默認(rèn)游戲圖標(biāo)等等,這些圖片很多地方都會(huì)用到而芥,如果每次都去讀取圖片律罢,由于讀取文件需要硬件操作,速度較慢棍丐,會(huì)導(dǎo)致性能較低误辑,所以我們考慮把圖片緩存起來沧踏,需要的時(shí)候直接從內(nèi)存中讀取,但是由于圖片占用內(nèi)存空間較大巾钉,緩存很多圖片需要很多內(nèi)存翘狱,就可能比較容易發(fā)生OOM異常,這個(gè)時(shí)候我們就可以考慮使用軟/弱引用來避免這個(gè)問題砰苍。

    首先定義一個(gè)HashMap盒蟆,保存軟引用對(duì)象

    private Map <String, SoftReference<Bitmap>> imageCache =
        new HashMap <String, SoftReference<Bitmap>> ();
    

    使用軟引用之后,在OOM異常發(fā)生之前师骗,這些緩存的圖片資源的內(nèi)存空間可以被釋放掉的历等,從而避免內(nèi)存達(dá)到上限,避免Crash發(fā)生辟癌。

    如果只是想避免OOM異常的發(fā)生寒屯,則可以使用軟引用,如果對(duì)于性能更在意黍少,想盡快回收一些占用內(nèi)存比較大的對(duì)象寡夹,則可以使用弱引用

    另外可以根據(jù)對(duì)象是否經(jīng)常使用來判斷選擇軟引用還是弱引用,如果該對(duì)象經(jīng)常使用就盡量使用軟引用厂置,如果該對(duì)象不被使用的可能性更大些就可以使用弱引用

  7. 避免override finalize()

    • finalize()方法被執(zhí)行的時(shí)間不確定菩掏,不能依賴于它來釋放緊缺的資源,時(shí)間不確定的原因是:虛擬機(jī)調(diào)用GC的時(shí)間不確定 Finalize daemon線程被調(diào)用的時(shí)間不確定昵济。

    • finalize方法只會(huì)被執(zhí)行以次智绸,即使對(duì)象被復(fù)活了,如果已經(jīng)執(zhí)行過finalize方法再次被GC時(shí)也不會(huì)再執(zhí)行了访忿,原因是:含有finalize方法的object是在new 的時(shí)候由虛擬機(jī)生成一個(gè)finalize Reference在來引用到該Object的瞧栗,而在finalize方法執(zhí)行的時(shí)候,該Object所對(duì)應(yīng)的finalize Reference會(huì)被釋放掉海铆,即使在這個(gè)時(shí)候把object復(fù)活迹恐,再第二次被GC的時(shí)候由于沒有了finalize Reference與之對(duì)應(yīng),所以finalize不會(huì)再執(zhí)行卧斟。

    • 含有Finalize方法的object需要至少經(jīng)歷兩次GC才有可能被釋放殴边。

  8. 資源未關(guān)閉而造成的內(nèi)存泄漏

    對(duì)于使用了BreadcastReceiver、ContentObserve珍语,F(xiàn)ile锤岸,游標(biāo)Cursor,Stream廊酣,Bitmap等資源的使用能耻,應(yīng)該在Activity銷毀時(shí)及時(shí)關(guān)閉或者注銷,否則這些資源將不會(huì)被回收,造成內(nèi)存泄漏

總結(jié)

對(duì)Activity等組件的引用應(yīng)該控制在Activity的生命周期內(nèi)晓猛,如果不能就考慮使用getApplicationContext或者getApplication饿幅,避免Activity被外部長生命周期的對(duì)象引用而泄漏

盡量不要在靜態(tài)變量或者靜態(tài)內(nèi)部類中使用非靜態(tài)外部成員變量(包括context),如果不能避免使用戒职,要考慮及時(shí)把外部成員變量置空栗恩,也可以在內(nèi)部類中使用弱引用來引用外部類的變量

對(duì)于長生命周期比Activity長的內(nèi)部類對(duì)象,并且內(nèi)部類中使用了外部類的成員變量洪燥,可以這樣避免內(nèi)存泄漏

將內(nèi)部類改為靜態(tài)內(nèi)部類

靜態(tài)內(nèi)部類中使用弱引用來引用外部類的成員變量

Handler的持有的引用對(duì)象最好使用弱引用磕秤,資源釋放也可以情況Handler里面的消息,比如在Activity onStop或者onDestroy的時(shí)候取消哎Handler對(duì)象的Message和Runnable

在Java的實(shí)現(xiàn)過程中捧韵,也要考慮其對(duì)象釋放市咆,最好的辦法是在不使用某個(gè)對(duì)象時(shí),顯式的將此對(duì)象賦值為null再来,比如使用完Bitmap后先調(diào)用recycle蒙兰,在賦值為null,清空對(duì)圖片等資源又直接引用或間接引用的數(shù)組芒篷,最后遵循誰先創(chuàng)建釋放誰的原則

正確關(guān)閉資源搜变,對(duì)于使用了BreadcastReceiver、ContentObserve针炉,F(xiàn)ile挠他,游標(biāo)Cursor,Stream篡帕,Bitmap等資源的使用殖侵,應(yīng)該在Activity銷毀時(shí)及時(shí)關(guān)閉或者注銷。

好了赂苗,到此就內(nèi)存泄露以及Android中常見的內(nèi)存泄露場(chǎng)景就介紹的差不多愉耙。當(dāng)然,以上觀點(diǎn)僅僅是小編的管中窺豹拌滋,肯定還有許多未知的場(chǎng)景沒有覆蓋。如果有疑問或不對(duì)的地方猜谚,請(qǐng)不吝賜教败砂。如果覺得有收獲,請(qǐng)點(diǎn)贊魏铅,喜歡哦~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昌犹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子览芳,更是在濱河造成了極大的恐慌斜姥,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異铸敏,居然都是意外死亡缚忧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門杈笔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闪水,“玉大人,你說我怎么就攤上這事蒙具∏蛴埽” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵禁筏,是天一觀的道長持钉。 經(jīng)常有香客問我,道長篱昔,這世上最難降的妖魔是什么每强? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮旱爆,結(jié)果婚禮上舀射,老公的妹妹穿的比我還像新娘。我一直安慰自己怀伦,他們只是感情好脆烟,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著房待,像睡著了一般邢羔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桑孩,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天拜鹤,我揣著相機(jī)與錄音,去河邊找鬼流椒。 笑死敏簿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宣虾。 我是一名探鬼主播惯裕,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绣硝!你這毒婦竟也來了蜻势?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤鹉胖,失蹤者是張志新(化名)和其女友劉穎握玛,沒想到半個(gè)月后够傍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挠铲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年冕屯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片市殷。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愕撰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出醋寝,到底是詐尸還是另有隱情搞挣,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布音羞,位于F島的核電站囱桨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嗅绰。R本人自食惡果不足惜舍肠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窘面。 院中可真熱鬧翠语,春花似錦、人聲如沸财边。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酣难。三九已至谍夭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間憨募,已是汗流浹背紧索。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菜谣,地道東北人珠漂。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像尾膊,于是被迫代替她去往敵國和親甘磨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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