1. 程式人生 > >android中不小心使用靜態變數會導致記憶體洩露

android中不小心使用靜態變數會導致記憶體洩露

     在android 專案開發過程中,不小心可能就會導致activity的記憶體洩露,即使使用者在使用APP的時候並沒有感受到記憶體洩露給APP帶來毀滅性的奔潰,但我們開發者可以通過除錯能夠很明顯的看到有些佔用的記憶體死也GC不掉。

     OK ,隔壁家老伍來講解一個,老伍親身經歷的怪事,APP在啟動時我們都有加啟動頁面,為了好看,有時還會新增一些動畫效果,可怕的是啟動頁面是一張比較大點的圖片,啟動完以後Activity被finish()掉,我們的理想是希望啟動頁結束後,佔用的記憶體也能過及時銷燬,避免一些無謂的記憶體佔用。怪就怪這塊記憶體怎麼GC都GC不掉,佛主啊,佛主,這是是為啥子羅。

    筆者接下來找原因,java的記憶體回收機制還是很強大的,很明顯這個快佔用的記憶體一定還被某個物件引用著,程式碼分析下來啟動頁面時加了一個過度動畫,專案中有一個Util類,類裡面提供了兩個靜態成語變數

     private static Animation alphaShowAnimation = null;
     private static Animation alphaHideAnimation = null;

    載入動畫的方法 public static void startViewLeftAnimation(final View view, boolean

isShow, Contextcontext)

   注意引數View被final 修飾了,函式體裡面的方法實現

   if (alphaHideAnimation == null) {
                alphaHideAnimation = AnimationUtils.loadAnimation(context, R.anim.animation_hide);
       }
       alphaHideAnimation.setAnimationListener(new AnimationListener() {


                @Override
                public void onAnimationStart(Animation arg0) {
                    // TODO Auto-generated method stub
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                    // TODO Auto-generated method stub


                }


                @Override
                public void onAnimationEnd(Animation arg0) {
                    // TODO Auto-generated method stub
                    view.setVisibility(View.GONE);
                }
            });

 注意看在動畫結束後呼叫了view.setVisibility(View.GONE), 也就是說使用了Activity 傳遞過來的view ,那麼問題來了alphaHideAnimation又是靜態變數,它生命週期老長老長的,沒出意外的話可以活500年,仔細分析在一個靜態成員的變數中保留了Activity裡面的一個檢視,可惡的是檢視中保留了Context的引用,這個時候就產生了一個物件長期被引用,導致Activity無法被GC掉,Activity佔用的記憶體也無法被GC掉。這個時候記憶體溢位發生了。

 建議動畫少用靜態成員,儘量保持生命週期在函授體內,使用靜態成員時要檢查有沒有長期引用且需要銷燬的物件。

這是一個簡單的Actiivty記憶體溢位,可以通過程式碼邏輯就能夠分析出來,複雜一點的我們使用Mat工具來分析。