[老實(shí)李] Android 內(nèi)存泄漏全解析

一、什么是內(nèi)存泄漏

內(nèi)存泄露 memory leak,是指程序在申請(qǐng)內(nèi)存后硝拧,無(wú)法釋放已申請(qǐng)的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略葛假,但內(nèi)存泄露堆積后果很?chē)?yán)重障陶,無(wú)論多少內(nèi)存,遲早會(huì)被占光。memory leak會(huì)最終會(huì)導(dǎo)致out of memory聊训!

內(nèi)存泄漏是指你向系統(tǒng)申請(qǐng)分配內(nèi)存進(jìn)行使用(new)咸这,可是使用完了以后卻不歸還(delete),結(jié)果你申請(qǐng)到的那塊內(nèi)存你自己也不能再訪(fǎng)問(wèn)(也許你把它的地址給弄丟了)魔眨,而系統(tǒng)也不能再次將它分配給需要的程序。一個(gè)盤(pán)子用盡各種方法只能裝4個(gè)果子酿雪,你裝了5個(gè)遏暴,結(jié)果掉倒地上不能吃了。這就是溢出指黎!比方說(shuō)棧朋凉,棧滿(mǎn)時(shí)再做進(jìn)棧必定產(chǎn)生空間溢出,叫上溢醋安,椩优恚空時(shí)再做退棧也產(chǎn)生空間溢出,稱(chēng)為下溢吓揪。就是分配的內(nèi)存不足以放下數(shù)據(jù)項(xiàng)序列,稱(chēng)為內(nèi)存溢出.

二亲怠、Java 內(nèi)存分配策略

知道了什么是內(nèi)存泄漏,我們就不得不提Java 的內(nèi)存分配策略柠辞。Java程序運(yùn)行時(shí)的內(nèi)存分配策略有三種团秽,分別是靜態(tài)分配棧式分配,和堆式分配习勤。對(duì)應(yīng)的三種策略使用的內(nèi)存空間是要分別是靜態(tài)存儲(chǔ)區(qū)(也稱(chēng)方法區(qū))踪栋,棧區(qū),和堆區(qū)图毕。

  • 靜態(tài)存儲(chǔ)區(qū)(方法區(qū)):主要存放靜態(tài)數(shù)據(jù)夷都,全局static數(shù)據(jù)和常量。這塊內(nèi)存在程序編譯時(shí)就已經(jīng)分配好予颤,并且在程序整個(gè)運(yùn)行期間都存在囤官。
  • 棧區(qū):當(dāng)方法執(zhí)行時(shí),方法內(nèi)部的局部變量都建立在棧內(nèi)存中荣瑟,并在方法結(jié)束后自動(dòng)釋放分配的內(nèi)存治拿。因?yàn)闂?nèi)存分配是在處理器的指令集當(dāng)中所以效率很高,但是分配的內(nèi)存容量有限笆焰。
  • 堆區(qū):又稱(chēng)動(dòng)態(tài)內(nèi)存分配劫谅,通常就是指在程序運(yùn)行時(shí)直接new出來(lái)的內(nèi)存。這部分內(nèi)存在不適用時(shí)將會(huì)由Java垃圾回收器來(lái)負(fù)責(zé)回收嚷掠。

堆與棧的區(qū)別

在方法體內(nèi)定義的(局部變量)一些基本類(lèi)型的變量和對(duì)象的引用變量都在方法的棧內(nèi)存中分配捏检。
堆內(nèi)存用來(lái)存放所有new出來(lái)的對(duì)象(包括該對(duì)象內(nèi)的所有成員變量)和數(shù)組。
在堆中分配的內(nèi)存不皆,由Java垃圾回收管理器來(lái)自動(dòng)管理贯城。

public class Sample {
    int s1 = 0;
    Sample mSample1 = new Sample();

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

如上局部變量s2和mSample2存放在棧內(nèi)存中,mSample3所指向的對(duì)象存放在堆內(nèi)存中霹娄,包括該對(duì)象的成員變量s1和mSample1也存放在堆中能犯,而它自己則存放在棧中( 這句話(huà)的意思就是 Sample mSample3 是在棧中的,而 new Sample()是在堆中的,mSample3就是個(gè)引用變量犬耻,我們可以通過(guò)引用變量訪(fǎng)問(wèn)堆內(nèi)存中的對(duì)象或者數(shù)組 )踩晶。

結(jié)論
局部變量的基本類(lèi)型和引用存儲(chǔ)在棧內(nèi)存中,引用的實(shí)體存儲(chǔ)在堆中枕磁《沈撸——因它們存在于方法中,隨方法的生命周期而結(jié)束计济。
成員變量全部存儲(chǔ)于堆中(包括基本數(shù)據(jù)類(lèi)型茸苇,引用和引用的對(duì)象實(shí)體)÷偌牛——因?yàn)樗鼈儗儆陬?lèi)学密,類(lèi)對(duì)象終究要被new出來(lái)使用。

Java GC 原理與算法機(jī)制

由程序分配內(nèi)存传藏,GC來(lái)釋放內(nèi)存则果。內(nèi)存釋放的原理為該對(duì)象或者數(shù)組不再被引用幔翰,則JVM會(huì)在適當(dāng)?shù)臅r(shí)候回收內(nèi)存。

GC機(jī)制判斷對(duì)象是否存活的算法:

  1. 引用計(jì)數(shù)算法
    給對(duì)象添加一個(gè)引用計(jì)數(shù)器西壮,當(dāng)有一個(gè)地方引用它時(shí)遗增,計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí)款青,計(jì)數(shù)器就減1做修;任何時(shí)候計(jì)數(shù)器都為0的對(duì)象就是不可能再被使用的。引用計(jì)數(shù)器算法(Reference Counting)實(shí)現(xiàn)簡(jiǎn)單抡草,判定效率也很高饰及,在大部分情況下他都是一個(gè)不錯(cuò)的算法。但是康震,Java語(yǔ)言中沒(méi)有選用引用計(jì)數(shù)算法來(lái)管理內(nèi)存燎含,其中最主要的原因是他很難解決對(duì)象之間的互相循環(huán)引用的問(wèn)題。

  2. 根搜索算法(GC Roots Tracing)
    基本思路是通過(guò)一系列名為“GC Roots”的對(duì)象作為起始點(diǎn)腿短,從這個(gè)節(jié)點(diǎn)開(kāi)始向下搜索屏箍,搜索所走過(guò)的路徑稱(chēng)為引用鏈(Reference Chain),當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連(用圖論術(shù)語(yǔ)描述就是從GC Roots到這個(gè)對(duì)象不可達(dá))時(shí),則證明此對(duì)象是不可用的橘忱。在主流的商用程序語(yǔ)言中(Java赴魁、C#),都是使用根搜索算法判定對(duì)象是否存活的。

常見(jiàn)回收算法:

  1. 標(biāo)記-清除算法:標(biāo)記階段:先通過(guò)根節(jié)點(diǎn)钝诚,標(biāo)記所有從根節(jié)點(diǎn)開(kāi)始的可達(dá)對(duì)象颖御。因此,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象凝颇;清除階段:清除所有未被標(biāo)記的對(duì)象潘拱。
  2. 復(fù)制算法:(新生代的GC)將原有的內(nèi)存空間分為兩塊,每次只使用其中一塊拧略,在垃圾回收時(shí)泽铛,將正在使用的內(nèi)存中的存活對(duì)象復(fù)制到未使用的內(nèi)存塊中,然后清除正在使用的內(nèi)存塊中的所有對(duì)象辑鲤。
  3. 標(biāo)記-整理算法:(老年代的GC)標(biāo)記階段:先通過(guò)根節(jié)點(diǎn),標(biāo)記所有從根節(jié)點(diǎn)開(kāi)始的可達(dá)對(duì)象杠茬。因此月褥,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象整理階段:將將所有的存活對(duì)象壓縮到內(nèi)存的一端;之后瓢喉,清理邊界外所有的空間
  4. 分代收集算法:存活率低:少量對(duì)象存活宁赤,適合復(fù)制算法:在新生代中,每次GC時(shí)都發(fā)現(xiàn)有大批對(duì)象死去栓票,只有少量存活(新生代中98%的對(duì)象都是“朝生夕死”)决左,那就選用復(fù)制算法愕够,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成GC。存活率高:大量對(duì)象存活佛猛,適合用標(biāo)記-清理/標(biāo)記-整理:在老年代中惑芭,因?yàn)閷?duì)象存活率高、沒(méi)有額外空間對(duì)他進(jìn)行分配擔(dān)保继找,就必須使用“標(biāo)記-清理”/“標(biāo)記-整理”算法進(jìn)行GC遂跟。

三、導(dǎo)致內(nèi)存泄漏的原因

一句話(huà):長(zhǎng)生命周期的對(duì)象持有短生命周期的對(duì)象婴渡。短生命周期對(duì)象無(wú)法及時(shí)釋放幻锁。

導(dǎo)致內(nèi)存泄漏主要的原因是,先前申請(qǐng)了內(nèi)存空間而忘記了釋放边臼。如果程序中存在對(duì)無(wú)用對(duì)象的引用哄尔,那么這些對(duì)象就會(huì)駐留內(nèi)存,消耗內(nèi)存柠并,因?yàn)闊o(wú)法讓垃圾回收器GC驗(yàn)證這些對(duì)象是否不再需要岭接。如果存在對(duì)象的引用,這個(gè)對(duì)象就被定義為"有效的活動(dòng)"堂鲤,同時(shí)不會(huì)被釋放亿傅。要確定對(duì)象所占內(nèi)存將被回收,我們就要?jiǎng)?wù)必確認(rèn)該對(duì)象不再會(huì)被使用瘟栖。典型的做法就是把對(duì)象數(shù)據(jù)成員設(shè)為null或者從集合中移除該對(duì)象葵擎。但當(dāng)局部變量不需要時(shí),不需明顯的設(shè)為null半哟,因?yàn)橐粋€(gè)方法執(zhí)行完畢時(shí)酬滤,這些引用會(huì)自動(dòng)被清理。

  • static變量引用待釋放類(lèi)實(shí)例
    比如MainActivity里面有一個(gè)靜態(tài)的變量sMainActivity = this,這就會(huì)照成內(nèi)存泄漏寓涨,比如靜態(tài)集合類(lèi)沒(méi)有及時(shí)setnull
  • 單例
  1. 如果此時(shí)傳入的是 Application 的 Context盯串,因?yàn)?Application 的生命周期就是整個(gè)應(yīng)用的生命周期,所以這將沒(méi)有任何問(wèn)題戒良。
  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ì)被回收,這就造成泄漏了沃呢。
  • 資源對(duì)象沒(méi)有關(guān)閉
    廣播沒(méi)有反注冊(cè)年栓,EventBus沒(méi)有反注冊(cè),Cursor對(duì)象沒(méi)有關(guān)薄霜,流沒(méi)有關(guān) 等等
  • 集合類(lèi)泄漏
List<Object> objectList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Object o = new Object();
            objectList.add(o);
            o = null;
        }

上面的實(shí)例某抓,雖然在循環(huán)中把引用o釋放了纸兔,但是它被添加到了objectList中,所以objectList也持有對(duì)象的引用否副,此時(shí)該對(duì)象是無(wú)法被GC的汉矿。因此對(duì)象如果添加到集合中,還必須從中刪除副编,最簡(jiǎn)單的方法

        //釋放objectList
        objectList.clear();
        objectList=null;
  • webview內(nèi)存泄漏
    webview是開(kāi)啟的一個(gè)子線(xiàn)程负甸,如果子線(xiàn)程沒(méi)有運(yùn)行結(jié)束就銷(xiāo)毀了activity的話(huà),那么子線(xiàn)程還是持有activity的痹届,這時(shí)候就產(chǎn)生了內(nèi)存泄漏
  • Handler使用非靜態(tài)的時(shí)候
    我們知道非static的內(nèi)部類(lèi)會(huì)持有外部類(lèi)的引用呻待,如果此時(shí)Handler從消息隊(duì)列有未處理的Message,在Activity finish之后Message還是存在队腐,那么Handler也存在蚕捉,handler里面又有Context的引用,也就是Activity也存在柴淘,那就發(fā)生了內(nèi)存泄漏迫淹。
    解決辦法:靜態(tài)內(nèi)部類(lèi),即使用static修飾Handler为严,通過(guò) WeakReference 來(lái)保持外部的Activity對(duì)象敛熬。
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler{
    private final WeakReference<Activity> mActivity;
    public MyHandler(Activity activity) {
        mActivity = new WeakReference<Activity>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
        System.out.println(msg);
        if(mActivity.get() == null) {
            return;
        }
    }
}

四、解決內(nèi)存泄漏的途徑

下面演示幾個(gè)使用LeakCanary解決內(nèi)存泄漏的例子
1第股、消滅Context泄漏
泄漏原因:將Activity當(dāng)做Context對(duì)象使用

消滅Context泄漏.jpg

這就是一條內(nèi)存泄漏過(guò)程的引用鏈应民,這條引用鏈最后一行的位置是泄漏發(fā)生的地方,第一行是泄漏的源頭夕吻,我們主要觀(guān)察的地方就是內(nèi)存泄漏的源頭部分诲锹。比如,上面的內(nèi)存泄漏的源頭就是MainActivity中使用了MainActivity這個(gè)Activity作為Context所引起的內(nèi)存泄漏涉馅。

Image.png

解決方式就是使用ApplicationContext代替Activity Context

2归园、消滅static引用

消滅static引用.jpg

可以看到在代碼中使用了static修飾的變量dialog,static關(guān)鍵字修飾的dialog屬于類(lèi)所有稚矿,而不屬于任何特定的實(shí)例庸诱,所以即使UploadDataDialog銷(xiāo)毀了,dialog還是存在的晤揣。所以在Dialog銷(xiāo)毀的時(shí)候這個(gè)static變量不能被GC回收桥爽,所以我們要重寫(xiě)dismiss方法,當(dāng)UploadDataDialog dismiss的時(shí)候我們就讓其將成員變量dialog置為空即可碉渡。

public class UploadDataDialog  extends Dialog{
    private Context context;
    private static UploadDataDialog dialog;
    private ImageView ivProgress;

    public UploadDataDialog(Context context) {
        super(context);
        this.context = context;
    }

    public UploadDataDialog(Context context, int themeResId) {
        super(context, themeResId);
        this.context = context;

    }

    public static UploadDataDialog showDialog(Context context){
        dialog = new UploadDataDialog(context, R.style.UploadDataDialog);
        dialog.setContentView(R.layout.dialog_uploaddata);
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(hasFocus && dialog != null){
            ivProgress = (ImageView) dialog.findViewById(R.id.ivProgress);
            Animation animation = AnimationUtils.loadAnimation(context, R.anim.dialog_progress_anim);
            ivProgress.startAnimation(animation);
        }
    }

    @Override
    public void dismiss() {
        super.dismiss();
        if (dialog != null) {
            dialog = null;
        }
    }
}

3、使用暴力反射解決內(nèi)存泄漏問(wèn)題

暴力反射解決內(nèi)存泄漏問(wèn)題.png

這個(gè)問(wèn)題還是比較奇怪的母剥,我使用LocalBroadcastManager管理各種監(jiān)聽(tīng)的注冊(cè)反注冊(cè)滞诺,但是現(xiàn)在提示我LocalBroadcastManager中的mInstance出現(xiàn)了泄漏形导,而LocalBroadcastManager是Android SDK中的,所以只能通過(guò)暴力反射來(lái)拿到這個(gè)成員變量然后置空习霹。

@Override
protected void onDestroy() {
    super.onDestroy();
   
    try {
        Class clazz = Class.forName("android.support.v4.content.LocalBroadcastManager");
        //獲取成員屬性mInstance(單例對(duì)象)
        Field field = clazz.getDeclaredField("mInstance");
        //設(shè)置private屬性可訪(fǎng)問(wèn)
        if (field.isAccessible() == false) {
            field.setAccessible(true);
        }
        //置空屬性
        field.set(null, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

4朵耕、一個(gè)java內(nèi)存泄漏的例子

class MyList{  
      
    /* 
     * 此處只為掩飾效果,并沒(méi)有進(jìn)行封裝之類(lèi)的操作 
     *  
     * 將List集合用關(guān)鍵字 static 聲明淋叶,這時(shí)這個(gè)集合將不屬于任何  MyList 對(duì)象阎曹,而是一個(gè)類(lèi)成員變量 
     *  
     */  
    public static List<String> list = new ArrayList<String>();  
      
}  
  
 class Demmo{  
     public static void main(String[] args) {  
         MyList list = new MyList();  
         list.list.add("123456");  
         // 此時(shí)即便我們將 list指向null,仍然存在內(nèi)存泄漏煞檩,因?yàn)镸yList中的list是靜態(tài)的处嫌,它屬于類(lèi)所有而不屬于任何特定的實(shí)例  
         list = null;  
    }  
 }  
Image.png

五、LeakCanary解決內(nèi)存泄露的原理

LeakCanary 在 Application 中安裝完成后斟湃,會(huì)注冊(cè)對(duì)應(yīng)用內(nèi)所有 Activity 生命周期的監(jiān)聽(tīng)熏迹,也就是在Activity的onDestroy的時(shí)候?qū)ctivity傳到watch方法中,然后在watch方法中的時(shí)候會(huì)把a(bǔ)ctivity包裝成一個(gè)弱引用凝赛。并且為這個(gè)弱引用指定了一個(gè)隊(duì)列注暗,這個(gè)隊(duì)列的作用就是當(dāng)發(fā)生GC后,弱引用就會(huì)被放到這個(gè)隊(duì)列里面墓猎。(Activity如果被強(qiáng)引用的話(huà)捆昏,就不會(huì)放到這個(gè)隊(duì)列里面了,也就是內(nèi)存泄漏了毙沾。)所以我們就可以通過(guò)手動(dòng)執(zhí)行一下GC操作骗卜,來(lái)看隊(duì)列里面是不是包含這個(gè)activity對(duì)象,如果不包含就是內(nèi)存泄漏搀军。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膨俐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子罩句,更是在濱河造成了極大的恐慌焚刺,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件门烂,死亡現(xiàn)場(chǎng)離奇詭異乳愉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)屯远,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)蔓姚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人慨丐,你說(shuō)我怎么就攤上這事坡脐。” “怎么了房揭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵备闲,是天一觀(guān)的道長(zhǎng)晌端。 經(jīng)常有香客問(wèn)我,道長(zhǎng)恬砂,這世上最難降的妖魔是什么咧纠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮泻骤,結(jié)果婚禮上漆羔,老公的妹妹穿的比我還像新娘。我一直安慰自己狱掂,他們只是感情好演痒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著符欠,像睡著了一般嫡霞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上希柿,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天诊沪,我揣著相機(jī)與錄音,去河邊找鬼曾撤。 笑死端姚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挤悉。 我是一名探鬼主播渐裸,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼装悲!你這毒婦竟也來(lái)了昏鹃?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诀诊,失蹤者是張志新(化名)和其女友劉穎洞渤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體属瓣,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡载迄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抡蛙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片护昧。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖粗截,靈堂內(nèi)的尸體忽然破棺而出惋耙,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布绽榛,位于F島的核電站遥金,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蒜田。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一选泻、第九天 我趴在偏房一處隱蔽的房頂上張望冲粤。 院中可真熱鬧,春花似錦页眯、人聲如沸梯捕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)傀顾。三九已至,卻和暖如春碌奉,著一層夾襖步出監(jiān)牢的瞬間短曾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工赐劣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫉拐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓魁兼,卻偏偏與公主長(zhǎng)得像婉徘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咐汞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

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

  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們?cè)陂_(kāi)發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問(wèn)題盖呼。內(nèi)存泄漏...
    _痞子閱讀 1,639評(píng)論 0 8
  • 內(nèi)存管理的目的就是讓我們?cè)陂_(kāi)發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問(wèn)題。內(nèi)存泄漏大家都不陌生了化撕,簡(jiǎn)單粗俗的講几晤,...
    DreamFish閱讀 793評(píng)論 0 5
  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們?cè)陂_(kāi)發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問(wèn)題。內(nèi)存泄漏...
    apkcore閱讀 1,222評(píng)論 2 7
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,290評(píng)論 25 707
  • 昨晚凍的牛奶蔓越莓侯谁,今早起來(lái)一顆顆裝盤(pán)锌仅,然后忍不住嘗了一顆,透心涼墙贱,酸甜中透著牛奶的淡淡清香热芹,很是不錯(cuò)。 一直很喜...
    蜜蜜姐姐閱讀 267評(píng)論 0 1