女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是內(nèi)存泄漏?android中導(dǎo)致內(nèi)存泄漏的主要幾個(gè)點(diǎn)

哆啦安全 ? 來源:程序員Android ? 2024-02-20 10:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

當(dāng)一個(gè)對(duì)象已經(jīng)不需要在使用了,本應(yīng)該被回收,而另一個(gè)正在使用的對(duì)象持有它的引用,導(dǎo)致對(duì)象不能被回收。因?yàn)椴荒鼙患皶r(shí)回收的本該被回收的內(nèi)存,就產(chǎn)生了內(nèi)存泄漏。如果內(nèi)存泄漏太多會(huì)導(dǎo)致程序沒有辦法申請(qǐng)內(nèi)存,最后出現(xiàn)內(nèi)存溢出的錯(cuò)誤。

二、android中導(dǎo)致內(nèi)存泄漏的主要幾個(gè)點(diǎn)

android開發(fā)中經(jīng)常出現(xiàn)的點(diǎn),我有只有了解了,才能更好的避免。

使用單例模式

使用匿名內(nèi)部類

使用異步事件處理機(jī)制Handler

使用靜態(tài)變量

資源未關(guān)閉

設(shè)置監(jiān)聽

使用AsyncTask

使用Bitmap

上面就是我列出的幾個(gè)常出現(xiàn)內(nèi)存泄漏的幾個(gè)點(diǎn),下面我們將一一解讀。

三、java虛擬機(jī)內(nèi)存管理

5f5b9194-cf87-11ee-a297-92fbcf53809c.jpg

java虛擬機(jī)內(nèi)存分為虛擬機(jī)棧,本地方法棧,程序計(jì)數(shù)器,堆,方法區(qū)這幾個(gè)模塊,下面我們就來分析下各個(gè)模塊。

(1).虛擬機(jī)棧

虛擬機(jī)棧主要的作用就是為執(zhí)行java方法服務(wù)的,是Java方法執(zhí)行的動(dòng)態(tài)內(nèi)存模型。會(huì)導(dǎo)致棧內(nèi)存溢出(StackOverFlowError)

(2).本地方法棧

為執(zhí)行native方法服務(wù)的,其他和虛擬機(jī)棧一樣

(3).程序計(jì)數(shù)器

是當(dāng)前線程執(zhí)行的字節(jié)碼行號(hào)指示器
處于線程獨(dú)占區(qū)
如果是執(zhí)行的是java代碼,當(dāng)前值為字節(jié)碼指令的地址,如果是Native,值為undefined

(4).堆

存放對(duì)象的實(shí)例
垃圾收集器管理的主要區(qū)域
分代管理對(duì)象
會(huì)導(dǎo)致內(nèi)存溢出(OutOfMemoryError)

(5).方法區(qū)

存放虛擬機(jī)加載的類信息,常量,靜態(tài)變量,編譯后的代碼和數(shù)據(jù)
GC主要對(duì)方法區(qū)進(jìn)行常量回收和類卸載
會(huì)出現(xiàn)內(nèi)存溢出(OutOfMemoryError)

四、java內(nèi)存幾種分配策略?

可以結(jié)合上面的內(nèi)存分配模型,能很好的理解。

(1).靜態(tài)的

靜態(tài)存儲(chǔ)區(qū):內(nèi)存在程序編譯期間就已經(jīng)分配完成,一般來說,這個(gè)區(qū)域在程序運(yùn)行期間一直處在
它主要儲(chǔ)存靜態(tài)數(shù)據(jù),全局靜態(tài)數(shù)據(jù)和常量

(2).棧式的

執(zhí)行方法時(shí),存儲(chǔ)局部變量(編譯期間,已經(jīng)確定占用內(nèi)存大小),操作數(shù),動(dòng)態(tài)鏈接,方法出口

(3).堆式的

也叫動(dòng)態(tài)內(nèi)存分配,主要存儲(chǔ)對(duì)象實(shí)例,以及已經(jīng)被加載類的Class對(duì)象(用于反射)

五、垃圾收集器是如何判斷對(duì)象是否可回收?

我們知道內(nèi)存泄漏的原因是應(yīng)該被回收的對(duì)象,不能被及時(shí)回收,那么GC是如何來判斷對(duì)象是否為垃圾對(duì)象呢?

判斷的方式有兩個(gè):

引用計(jì)數(shù)
對(duì)象被引用,引用計(jì)數(shù)器加1,反之減一,只有引用計(jì)數(shù)為0,那么這個(gè)對(duì)象為垃圾對(duì)象

可達(dá)性
從GCRoot節(jié)點(diǎn)對(duì)象開始,看是否可以訪問到此對(duì)象,如果沒有訪問到則為垃圾對(duì)象

可以作為GCRoot對(duì)象有以下幾種:
虛擬機(jī)棧中的局部變量
本地方法棧中的引用對(duì)象
方法區(qū)中的常量引用對(duì)象
方法區(qū)中的類屬性引用對(duì)象
在native層和早期的虛擬機(jī)一般使用引用計(jì)數(shù),但是現(xiàn)在的java虛擬機(jī)大多使用的是可達(dá)性。

六、什么是內(nèi)存抖動(dòng)?

堆內(nèi)存都有一定的大小,能容納的數(shù)據(jù)是有限制的,當(dāng)Java堆的大小太大時(shí),垃圾收集會(huì)啟動(dòng)停止堆中不再應(yīng)用的對(duì)象,來釋放內(nèi)存。當(dāng)在極短時(shí)間內(nèi)分配給對(duì)象和回收對(duì)象的過程就是內(nèi)存抖動(dòng)。

七、內(nèi)存抖動(dòng)產(chǎn)生的原因?

從術(shù)語上來講就是極短時(shí)間內(nèi)分配給對(duì)象和回收對(duì)象的過程。
一般多是在循環(huán)語句中創(chuàng)建臨時(shí)對(duì)象,在繪制時(shí)配置大量對(duì)象或者執(zhí)行動(dòng)畫時(shí)創(chuàng)建大量臨時(shí)對(duì)象
內(nèi)存抖動(dòng)會(huì)帶來UI的卡頓,因?yàn)榇罅康膶?duì)象創(chuàng)建,會(huì)很快消耗剩余內(nèi)存,導(dǎo)致GC回收,GC會(huì)占用大量的幀繪制時(shí)間,從而導(dǎo)致UI卡頓,關(guān)于UI卡頓會(huì)在后面章節(jié)講到。

八、android中4種引用

(1).StrongReference強(qiáng)引用
從不被回收,java虛擬機(jī)停止時(shí),才終止

(2).SoftReference軟引用
當(dāng)內(nèi)存不足時(shí),會(huì)主動(dòng)回收,使用SoftReference使用結(jié)合ReferenceQueue構(gòu)造有效期短

(3).WeakReference弱引用
每次垃圾回收時(shí),被回收

(4).PhatomReference虛引用
每次垃圾回收時(shí),被回收.結(jié)合ReferenceQueue來跟蹤對(duì)象被垃圾回收器回收的活動(dòng)

九、常見的導(dǎo)致內(nèi)存泄漏的示例

(1).使用單例模式

    private static ComonUtil mInstance = null;
    private Context mContext = null;

    public ComonUtil(Context context) {
        mContext = context;
    }

    public static ComonUtil getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new ComonUtil(context);
        }
        return mInstance;
    }

使用:

ComonUtil mComonUtil = ComonUtil.getInstance(this);

我們看到上面的代碼就是我們平時(shí)使用的單例模式,當(dāng)然這里沒有考慮線程安全,請(qǐng)忽略。當(dāng)我們傳遞進(jìn)來的是Context,那么當(dāng)前對(duì)象就會(huì)持有第一次實(shí)例化的Context,如果Context是Activity對(duì)象,那么就會(huì)產(chǎn)生內(nèi)存泄漏。因?yàn)楫?dāng)前對(duì)象ComonUtil是靜態(tài)的,生命周期和應(yīng)用是一樣的,只有應(yīng)用退出才會(huì)釋放,導(dǎo)致Activity不能及時(shí)釋放,帶來內(nèi)存泄漏。

怎么解決呢?

常見的有兩種方式,第一就是傳入ApplicationContext,第二CommonUtil中取context.getApplicationContext()。

    public ComonUtil(Context context) {
        mContext = context.getApplicationContext();
    }

(2).使用非靜態(tài)內(nèi)部類

    /**
     * 非靜態(tài)內(nèi)部類
     */
    public void createNonStaticInnerClass(){
        CustomThread mCustomThread = new CustomThread();
        mCustomThread.start();
    }

    public class CustomThread extends Thread{
        @Override
        public void run() {
            super.run();
            while (true){
                try {
                    Thread.sleep(5000);
                    Log.i(TAG,"CustomThread ------- 打印");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

我們就以線程為例,當(dāng)Activity調(diào)用了createNonStaticInnerClass方法,然后退出當(dāng)前Activity時(shí),因?yàn)榫€程還在后臺(tái)執(zhí)行且當(dāng)前線程持有Activity引用,只有等到線程執(zhí)行完畢,Activitiy才能得到釋放,導(dǎo)致內(nèi)存泄漏。
常用的解決方法有很多,第一把線程類聲明為靜態(tài)的類,如果要用到Activity對(duì)象,那么就作為參數(shù)傳入且為WeakReference,第二在Activity的onDestroy時(shí),停止線程的執(zhí)行。

public static class CustomThread extends Thread{
    private WeakReference mActivity;
    public CustomThread(MainActivity activity){
        mActivity = new WeakReference(activity)
    }
}

(3).使用異步事件處理機(jī)制Handler

    /**
     * 異步消息處理機(jī)制  -- handler機(jī)制
     */
    public void createHandler(){
        mHandler.sendEmptyMessage(0);
    }
    public Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            //處理耗時(shí)操作   
            return false;
        }
    });

這個(gè)應(yīng)該是我們平時(shí)使用最多的一種方式,如果當(dāng)handler中處理的是耗時(shí)操作,或者當(dāng)前消息隊(duì)列中消息很多時(shí),那當(dāng)Activity退出時(shí),當(dāng)前message中持有handler的引用,handler又持有Activity的引用,導(dǎo)致Activity不能及時(shí)的釋放,引起內(nèi)存泄漏的問題。

解決handler引起的內(nèi)存泄漏問題常用的兩種方式:

1.和上面解決Thread的方式一樣,

2.在onDestroy中調(diào)用mHandler.removeCallbacksAndMessages(null)

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }

(4).使用靜態(tài)變量

同單例引起的內(nèi)存泄漏。

(5).資源未關(guān)閉

常見的就是數(shù)據(jù)庫游標(biāo)沒有關(guān)閉,對(duì)象文件流沒有關(guān)閉,主要記得關(guān)閉就OK了。

(6).設(shè)置監(jiān)聽

常見的是在觀察者模式中出現(xiàn),我們?cè)谕顺鯝cviity時(shí)沒有取消監(jiān)聽,導(dǎo)致被觀察者還持有當(dāng)前Activity的引用,從而引起內(nèi)存泄漏。
常見的解決方法就是在onPause中注消監(jiān)聽

(7).使用AsyncTask

    public AsyncTask mTask = new AsyncTask() {

        @Override
        protected Object doInBackground(Object... params) {
            //耗時(shí)操作
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
        
        }   
    };

和上面同樣的道理,匿名內(nèi)部類持有外部類的引用,AsyncTask耗時(shí)操作導(dǎo)致Activity不能及時(shí)釋放,引起內(nèi)存泄漏。

解決方法同上:

1.聲明為靜態(tài)類,
2.在onPause中取消任務(wù)

(8).使用Bitmap

我們知道當(dāng)bitmap對(duì)象沒有被使用(引用),gc會(huì)回收bitmap的占用內(nèi)存,當(dāng)時(shí)這邊的內(nèi)存指的是java層的,那么本地內(nèi)存的釋放呢?我們可以通過調(diào)用bitmap.recycle()來釋放C層上的內(nèi)存,防止本地內(nèi)存泄漏




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3973

    瀏覽量

    130237
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2989

    瀏覽量

    109642
  • 虛擬機(jī)
    +關(guān)注

    關(guān)注

    1

    文章

    966

    瀏覽量

    29358
  • 內(nèi)存泄漏
    +關(guān)注

    關(guān)注

    0

    文章

    40

    瀏覽量

    9394

原文標(biāo)題:Android內(nèi)存泄漏知識(shí)點(diǎn)

文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Linux內(nèi)存泄漏檢測實(shí)現(xiàn)原理與實(shí)現(xiàn)

    在使用沒有垃圾回收的語言時(shí)(如 C/C++),可能由于忘記釋放內(nèi)存導(dǎo)致內(nèi)存被耗盡,這叫 內(nèi)存泄漏。由于內(nèi)核也需要自己管理
    發(fā)表于 12-09 11:11 ?1087次閱讀

    細(xì)說Linux內(nèi)存泄漏檢測實(shí)現(xiàn)原理與實(shí)現(xiàn)

    在使用沒有垃圾回收的語言時(shí)(如 C/C++),可能由于忘記釋放內(nèi)存導(dǎo)致內(nèi)存被耗盡,這叫 內(nèi)存泄漏。由于內(nèi)核也需要自己管理
    發(fā)表于 07-03 09:22 ?665次閱讀
    細(xì)說Linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>檢測實(shí)現(xiàn)原理與實(shí)現(xiàn)

    內(nèi)存泄漏定位該如何去實(shí)現(xiàn)呢

    嵌入式之內(nèi)存泄漏定位篇在嵌入式開發(fā)中,經(jīng)常會(huì)使用malloc,free分配釋放堆內(nèi)存,當(dāng)malloc,free不配對(duì)使用時(shí),就會(huì)導(dǎo)致內(nèi)存
    發(fā)表于 12-17 07:24

    分享一種內(nèi)存泄漏定位排查技巧

    常見的泄漏方式在嵌入式開發(fā)中,經(jīng)常會(huì)使用malloc,free分配釋放堆內(nèi)存,稍不小心就可能導(dǎo)致內(nèi)存點(diǎn)點(diǎn)地泄露,直至堆
    發(fā)表于 12-17 08:13

    內(nèi)存泄漏的特點(diǎn)和類型

    在計(jì)算機(jī)科學(xué)中,內(nèi)存泄漏(memory leak)指由于疏忽或錯(cuò)誤使程序未能釋放而造成不能再使用的內(nèi)存的情況。內(nèi)存泄漏并非指
    的頭像 發(fā)表于 06-20 10:58 ?3074次閱讀

    內(nèi)存泄漏問題原理及檢視方法

    可能不少開發(fā)者都遇到過內(nèi)存泄漏導(dǎo)致的網(wǎng)上問題,具體表現(xiàn)為單板在現(xiàn)網(wǎng)運(yùn)行數(shù)月以后,因?yàn)?b class='flag-5'>內(nèi)存耗盡而導(dǎo)致單板復(fù)位現(xiàn)象。一方面,
    的頭像 發(fā)表于 10-10 10:42 ?2844次閱讀

    什么是內(nèi)存泄漏內(nèi)存泄漏有哪些現(xiàn)象

    內(nèi)存泄漏幾乎是很難避免的,不管是老手還是新手,都存在這個(gè)問題,甚至 Windows 與 Linux 這類系統(tǒng)軟件也或多或少存在著內(nèi)存泄漏
    的頭像 發(fā)表于 09-05 17:24 ?1w次閱讀

    Linux內(nèi)存泄漏檢測實(shí)現(xiàn)原理與實(shí)現(xiàn)

    在使用沒有垃圾回收的語言時(shí)(如 C/C++),可能由于忘記釋放內(nèi)存導(dǎo)致內(nèi)存被耗盡,這叫 內(nèi)存泄漏
    的頭像 發(fā)表于 07-03 09:21 ?839次閱讀
    Linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>檢測實(shí)現(xiàn)原理與實(shí)現(xiàn)

    什么是內(nèi)存泄漏?如何避免JavaScript內(nèi)存泄漏

    JavaScript 代碼中常見的內(nèi)存泄漏的常見來源: 研究內(nèi)存泄漏問題就相當(dāng)于尋找符合垃圾回收機(jī)制的編程方式,有效避免對(duì)象引用的問題。
    發(fā)表于 10-27 11:30 ?674次閱讀
    什么是<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>?如何避免JavaScript<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>

    內(nèi)存泄漏如何避免

    的數(shù),那就是內(nèi)存溢出。 2. 內(nèi)存泄漏 內(nèi)存泄露 memory leak,是指程序在申請(qǐng)內(nèi)存后,無法釋放已申請(qǐng)的
    的頭像 發(fā)表于 11-10 11:04 ?1063次閱讀
    <b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>如何避免

    線程內(nèi)存泄漏問題的定位

    記錄一個(gè)關(guān)于線程內(nèi)存泄漏問題的定位過程,以及過程中的收獲。 1. 初步定位 是否存在內(nèi)存泄漏:想到內(nèi)存
    的頭像 發(fā)表于 11-13 11:38 ?900次閱讀
    線程<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>問題的定位

    如何發(fā)現(xiàn)內(nèi)存泄漏

    由于 C 和 C++ 程序中完全由程序員自主申請(qǐng)和釋放內(nèi)存,稍不注意,就會(huì)在系統(tǒng)中導(dǎo)入內(nèi)存錯(cuò)誤。同時(shí),內(nèi)存錯(cuò)誤往往非常嚴(yán)重,一般會(huì)帶來諸如系統(tǒng)崩潰,內(nèi)存耗盡這樣嚴(yán)重的 后果。本文將從靜
    的頭像 發(fā)表于 11-13 15:41 ?920次閱讀

    內(nèi)存溢出與內(nèi)存泄漏:定義、區(qū)別與解決方案

    與區(qū)別 1. 定義: 內(nèi)存溢出(Memory Overflow)指的是程序在申請(qǐng)內(nèi)存時(shí),無法獲得足夠的內(nèi)存空間,導(dǎo)致程序拋出異常或崩潰。當(dāng)程序需要的
    的頭像 發(fā)表于 12-19 14:10 ?3622次閱讀

    C語言內(nèi)存泄漏問題原理

    內(nèi)存泄漏問題只有在使用堆內(nèi)存的時(shí)候才會(huì)出現(xiàn),棧內(nèi)存不存在內(nèi)存泄漏問題,因?yàn)闂?/div>
    發(fā)表于 03-19 11:38 ?848次閱讀
    C語言<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>問題原理

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

    檢測內(nèi)存泄漏是軟件開發(fā)過程中一項(xiàng)至關(guān)重要的任務(wù),它有助于識(shí)別和解決那些導(dǎo)致程序占用過多內(nèi)存資源,從而影響程序性能甚至導(dǎo)致程序崩潰的問題。以下
    的頭像 發(fā)表于 07-30 11:50 ?3498次閱讀