smallseo.info

leakcanary

A memory leak detection library for Android and Java.

Memory Leak on AppCompatActivity using LeakCanary

I use LeakCanary and unfortunately got a leak and here is the logcat:

05-10 18:13:00.377    9098-9965/com.ponnex.justdrive D/LeakCanary﹕ In com.ponnex.justdrive:1.0:1.
* com.ponnex.justdrive.DebuggingActivity has leaked:
* GC ROOT static android.support.v4.content.LocalBroadcastManager.mInstance
* references android.support.v4.content.LocalBroadcastManager.mReceivers
* references java.util.HashMap.table
* references array java.util.HashMap$HashMapEntry[].[51]
* references java.util.HashMap$HashMapEntry.key
* references com.ponnex.justdrive.DebuggingActivity$3.this$0 (anonymous class extends android.content.BroadcastReceiver)
* leaks com.ponnex.justdrive.DebuggingActivity instance
* Reference Key: 4fea07d9-9369-4618-a8e0-9e63b3e1b908
* Device: samsung samsung GT-I9100 pa_i9100
* Android Version: 5.1.1 API: 22
* Durations: watch=5219ms, gc=244ms, heap dump=4978ms, analysis=19968ms

This is my DebuggingActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
LeakCanary.install(getApplication());
setContentView(R.layout.activity_debugging);
activityTV = (TextView) findViewById(R.id.debugText);
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(screenReceiver, new IntentFilter("com.ponnex.justdrive.ActivityRecognitionIntentService"));

}
private BroadcastReceiver screenReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String activity = intent.getStringExtra("Activity");
        updateUI(activity);
    }
};

public static void updateUI(String activity) {
    activityTV.setText(activity);
}

I've been checking my activity and tracing it out but I don't know how to fix this any help? :D

If you need more from my activity code I'll be glad to add or post them here ;)

---EDIT---

I also got a leak from another activity refering to snackbar(Snackbar by Nispok)

05-10 18:27:43.161   9098-16222/com.ponnex.justdrive D/LeakCanary﹕ In com.ponnex.justdrive:1.0:1.
* com.ponnex.justdrive.MainActivity has leaked:
* GC ROOT static com.nispok.snackbar.SnackbarManager.currentSnackbar
* references com.nispok.snackbar.Snackbar.mContext
* leaks com.ponnex.justdrive.MainActivity instance
* Reference Key: 1982a1a8-e66e-4218-9b5a-8f907ee26a7f
* Device: samsung samsung GT-I9100 pa_i9100
* Android Version: 5.1.1 API: 22
* Durations: watch=5291ms, gc=315ms, heap dump=4443ms, analysis=21801ms

Source: (StackOverflow)

LeakCanary - Activity is leaked as it implements SyncStatusObserver

I am using LeakCanary to identify memory leaks. I have an Activity which adds itself as the StatusChangeObserver in onResume as below:

    final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
            ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;

    mSyncObserverHandle = ContentResolver.addStatusChangeListener(mask, this);

And stops listening onPause

    ContentResolver.removeStatusChangeListener(mSyncObserverHandle);

When I exit the Activity, LeakCanary reports my Activity is leaked. Below is gist of the leak trace:

     * com.sample.android.MyListActivity has leaked:
     * GC ROOT android.content.ContentResolver$1.val$callback(anonymous class extends android.content.ISyncStatusObserver$Stub)
     * leaks com.sample.android.MyListActivity instance
     [ 06-11 15:35:23.123 11823:13392 D/LeakCanary ]
     * Reference Key: 1eaf447d-055c-4767-bb3f-56b12c7a4dae
     * Device: motorola motorola XT1022 condor_retaildsds
     * Android Version: 4.4.4 API: 19 LeakCanary: 1.3.1
     * Durations: watch=5029ms, gc=147ms, heap dump=693ms, analysis=15159ms
     [ 06-11 15:35:23.123 11823:13392 D/LeakCanary ]

I have tested on API 19 and 22. I would like to know if its a problem with my code or leakcanary or sdk.

Thanks in advance!


Source: (StackOverflow)

RxJava Observable Zip Causes Memory Leak

I am using RxJava's Observable.zip method to combine two API calls into one result. For some reason I am getting a memory leak despite the fact that I unsubscribe from the subscription. I am not sure if this a bug on my end or if there is something I need to do with the creation of the Observable.

protected void onCreate(Bundle bundle) {
...

subscription = Observable.zip(
      api.getConfiguration(),
      api.getSettings().map(r -> r.getData()),
      new Func2<ConfigurationResponse, List<Datum>, Struct>() {
        @Override
        public Struct call(ConfigurationResponse config, List<Datum> data) {
          return new Struct(data, config.getCopy(), config.getSettings());
        }
      }
    )
      .compose(Schedulers.applyApiSchedulers())
      .subscribe(
        struct -> {
          configurationManager.set(struct.data, struct.copy, struct.settings);
          startNextActivity();
        },
        error -> {
          startNextActivity();
        }
      );
}

protected void onDestroy() {
  if (!subscription.isUnsubscribed()) {
    subscription.unsubscribe();
  }
}

Here is the trace from Leak Canary.

leak trace

Any help would be appreciated.


Source: (StackOverflow)

Android Media player keeps app instance and cause a memory leak

I have an activity with a media player as a member variable.

My media player is initialized like this:

mMediaPlayer = new MediaPlayer(); 
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(MyActivity.this, URL); 
mMediaPlayer.prepareAsync(); 
//i set a on Prepared Listener to start playing on Prepared

Everything works just fine, and then i override my activity onStop method to release the Media Player.

if(mMediaPlayer!=null){
   if(mMediaPlayer.isPlaying()){
       mMediaPlayer.stop();
   }
   mMediaPlayer.release();
   mMediaPlayer=null;
}

But after the activity has stopped i get a memory leak report from LeakCanary.

The report is like this:

MyApp.Instance->

MyApp.mLoadedApk->

LoadedApk.mReceivers->

ArrayMap.mArray->

arrayObject[].[3]->

ArrayMap.mArray->

arrayObject[][0]->

MediaPlayer.mProxyReceiver->

MediaPlayer.mProxyContext->

leaks MyActivity instance.

MyApp.Instance->

MyApp.mLoadedApk->

LoadedApk.mReceivers->

ArrayMap.mArray->

arrayObject[].[3]->

ArrayMap.mArray->

arrayObject[][0]->

MediaPlayer.mProxyReceiver->

MediaPlayer.mProxyContext->

leaks MyActivity instance.

Yes i have a MyApp class which extends Application and i am holding a reference to MyApp instance in a static field, but i never use that reference in my activity, how can i solve this leak ?

[EDIT]

Here is the code of my Activity:

public class PlayActivity extends ActionBarActivity {

private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_play);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
protected void onStop() {
    super.onStop();
    if(mediaPlayer!=null){
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
        }
        mediaPlayer.release();
        mediaPlayer=null;
    }
}

public void playIt(View view){
    if(mediaPlayer==null){
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });


    }
    if(!mediaPlayer.isPlaying()){
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mediaPlayer.setDataSource(PlayActivity.this, Uri.parse("http://www.noiseaddicts.com/samples_1w72b820/142.mp3"));
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }



   }

 }

Source: (StackOverflow)

Retained fragment leak

I'm using the simple activity with the retained fragment which holds some data used by the activity. The retained fragment uses the loader to get the data from a content provider. On configuration change (screen rotation) the activity is recreated and the old instance is leaked as reported by LeakCanary library (retained fragment -> loader manager -> old activity). This reproduced with the support-v4 23.0.0 library (and the previous versions also). The sample of the activity with the retained fragment where leak is reproduced (no useful code here, only to demonstrate the leak):

package com.leaksample;

import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private ModelFragment mModelFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();
        mModelFragment = (ModelFragment) fm.findFragmentByTag(ModelFragment.TAG);
        if (mModelFragment == null) {
            mModelFragment = new ModelFragment();
            fm.beginTransaction()
                    .add(mModelFragment, ModelFragment.TAG)
                    .commit();
            fm.executePendingTransactions();
        }
    }

    public static class ModelFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
        private static final String TAG = ModelFragment.class.getSimpleName();

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
            getLoaderManager().initLoader(0, null, this);
        }

        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            return new CursorLoader(getActivity(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Images.Media.DATA}, null, null, null);
        }

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        }

        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
        }
    }
}

The stack from LeakCanary:

08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ In com.leaksample:1.0:1.
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * com.leaksample.MainActivity has leaked:
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * GC ROOT thread java.lang.Thread.<Java Local> (named 'Binder_1')
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * references android.view.ViewRootImpl.mContext
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * references com.leaksample.MainActivity.mModelFragment
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * references com.leaksample.MainActivity$ModelFragment.mLoaderManager
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * references android.support.v4.app.LoaderManagerImpl.mHost
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * references android.support.v4.app.FragmentActivity$HostCallbacks.this$0
08-29 19:52:34.129  15271-16632/com.leaksample D/LeakCanary﹕ * leaks com.leaksample.MainActivity instance

Maybe I'm doing something wrong and forgot to call some close or release method? I think using the retained fragment with the loader is a common pattern and should not be memory leaks here.


Source: (StackOverflow)

Understanding ViewTreeObserver leak

I am using LeakCanary 1.3.1-SNAPSHOT. I found a leak concerning ViewTreeObserver.OnScrollChangedListener setup and I fixed it like in the following code:

  private ViewTreeObserver.OnScrollChangedListener scrollViewChangeListener;

  @Override protected void onFinishInflate() {
      super.onFinishInflate();
      ButterKnife.inject(this);
      scrollViewChangeListener = new ViewTreeObserver.OnScrollChangedListener() {
      @Override public void onScrollChanged() {
        EventDetailsView.this.onScrollChanged(scrollView.getScrollY());
      }
    };
      scrollView.getViewTreeObserver()
        .addOnScrollChangedListener(scrollViewChangeListener);
  }
  @Override public void onDetachedFromWindow() {
      super.onDetachedFromWindow();
      scrollView.getViewTreeObserver().removeOnScrollChangedListener(scrollViewChangeListener);
  }

However LeakCanary still report it as a leak, any idea why?

* com.couchsurfing.mobile.ui.events.detail.EventDetailsScreen$Presenter has leaked:
* GC ROOT android.view.inputmethod.InputMethodManager$1.this$0 (anonymous class extends com.android.internal.view.IInputMethodClient$Stub)
* references android.view.inputmethod.InputMethodManager.mCurRootView
* references com.android.internal.policy.impl.PhoneWindow$DecorView.mAttachInfo
* references android.view.View$AttachInfo.mTreeObserver
* references android.view.ViewTreeObserver.mOnScrollChangedListeners
* references android.view.ViewTreeObserver$CopyOnWriteArray.mData
* references java.util.ArrayList.array
* references array java.lang.Object[].[0]
* references com.couchsurfing.mobile.ui.events.detail.EventDetailsView$1.this$0 (anonymous class implements android.view.ViewTreeObserver$OnScrollChangedListener)
* references com.couchsurfing.mobile.ui.events.detail.EventDetailsView.presenter
* leaks com.couchsurfing.mobile.ui.events.detail.EventDetailsScreen$Presenter instance* Reference Key: 69d0a429-ae27-48fc-a8e0-033c920dd07c
* Device: LGE google Nexus 5 hammerhead
* Android Version: 5.1 API: 22 LeakCanary: 1.3.1-SNAPSHOT
* Durations: watch=5032ms, gc=165ms, heap dump=2932ms, analysis=29907ms* Details:
* Instance of android.view.inputmethod.InputMethodManager$1
|   this$0 = android.view.inputmethod.InputMethodManager [id=0x130239c0]
|   mDescriptor = java.lang.String [id=0x6f5e3f38]
|   mObject = -1601862176
|   mOwner = android.view.inputmethod.InputMethodManager$1 [id=0x13112da0]
* Instance of android.view.inputmethod.InputMethodManager
|   static $staticOverhead = byte[] [id=0x6fe25d29;length=240;size=256]
|   static CONTROL_START_INITIAL = 256
|   static CONTROL_WINDOW_FIRST = 4
|   static CONTROL_WINDOW_IS_TEXT_EDITOR = 2
|   static CONTROL_WINDOW_VIEW_HAS_FOCUS = 1
|   static DEBUG = false
|   static DISPATCH_HANDLED = 1
|   static DISPATCH_IN_PROGRESS = -1
|   static DISPATCH_NOT_HANDLED = 0
|   static HIDE_IMPLICIT_ONLY = 1
|   static HIDE_NOT_ALWAYS = 2
|   static INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500
|   static MSG_BIND = 2
|   static MSG_DUMP = 1
|   static MSG_FLUSH_INPUT_EVENT = 7
|   static MSG_SEND_INPUT_EVENT = 5
|   static MSG_SET_ACTIVE = 4
|   static MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9
|   static MSG_TIMEOUT_INPUT_EVENT = 6
|   static MSG_UNBIND = 3
|   static NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1
|   static PENDING_EVENT_COUNTER = java.lang.String [id=0x6f5bb948]
|   static REQUEST_UPDATE_CURSOR_ANCHOR_INFO_NONE = 0
|   static RESULT_HIDDEN = 3
|   static RESULT_SHOWN = 2
|   static RESULT_UNCHANGED_HIDDEN = 1
|   static RESULT_UNCHANGED_SHOWN = 0
|   static SHOW_FORCED = 2
|   static SHOW_IMPLICIT = 1
|   static TAG = java.lang.String [id=0x6f5a76e0]
|   static sInstance = android.view.inputmethod.InputMethodManager [id=0x130239c0]
|   mActive = true
|   mBindSequence = 1523
|   mClient = android.view.inputmethod.InputMethodManager$1 [id=0x13112da0]
|   mCompletions = null
|   mCurChannel = android.view.InputChannel [id=0x1304a850]
|   mCurId = java.lang.String [id=0x1325dd80]
|   mCurMethod = com.android.internal.view.IInputMethodSession$Stub$Proxy [id=0x1304a840]
|   mCurRootView = com.android.internal.policy.impl.PhoneWindow$DecorView [id=0x12eac000]
|   mCurSender = android.view.inputmethod.InputMethodManager$ImeInputEventSender [id=0x12c72850]
|   mCurrentTextBoxAttribute = android.view.inputmethod.EditorInfo [id=0x133036c0]
|   mCursorAnchorInfo = null
|   mCursorCandEnd = 0
|   mCursorCandStart = 0
|   mCursorRect = android.graphics.Rect [id=0x13112d40]
|   mCursorSelEnd = 0
|   mCursorSelStart = 0
|   mDummyInputConnection = android.view.inputmethod.BaseInputConnection [id=0x13112dc0]
|   mFullscreenMode = false
|   mH = android.view.inputmethod.InputMethodManager$H [id=0x13112de0]
|   mHasBeenInactive = false
|   mIInputContext = android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper [id=0x13113310]
|   mLastSentUserActionNotificationSequenceNumber = -1
|   mMainLooper = android.os.Looper [id=0x12c76be0]
|   mNextServedView = com.couchsurfing.mobile.ui.drawer.DrawerView [id=0x131f8c00]
|   mNextUserActionNotificationSequenceNumber = 1
|   mPendingEventPool = android.util.Pools$SimplePool [id=0x13110fe0]
|   mPendingEvents = android.util.SparseArray [id=0x13112d80]
|   mRequestUpdateCursorAnchorInfoMonitorMode = 0
|   mServedConnecting = false
|   mServedInputConnection = null
|   mServedInputConnectionWrapper = null
|   mServedView = com.couchsurfing.mobile.ui.drawer.DrawerView [id=0x131f8c00]
|   mService = com.android.internal.view.IInputMethodManager$Stub$Proxy [id=0x13110fc0]
|   mTmpCursorRect = android.graphics.Rect [id=0x13112d20]
|   mViewToScreenMatrix = android.graphics.Matrix [id=0x13110fd0]
|   mViewTopLeft = int[] [id=0x13112d60;length=2;size=24]
* Instance of com.android.internal.policy.impl.PhoneWindow$DecorView
|   mActionMode = null
|   mActionModePopup = null
|   mActionModeView = null
|   mBackgroundFallback = com.android.internal.widget.BackgroundFallback [id=0x12fdd8e0]
|   mBackgroundPadding = android.graphics.Rect [id=0x12ffd9a0]
|   mBarEnterExitDuration = 250
|   mChanging = false
|   mDefaultOpacity = -1
|   mDownY = 0
|   mDrawingBounds = android.graphics.Rect [id=0x12ffd980]
|   mFeatureId = -1
|   mFrameOffsets = android.graphics.Rect [id=0x12ffd9e0]
|   mFramePadding = android.graphics.Rect [id=0x12ffd9c0]
|   mHideInterpolator = android.view.animation.PathInterpolator [id=0x12ffdb00]
|   mLastBottomInset = 144
|   mLastHasBottomStableInset = true
|   mLastHasTopStableInset = true
|   mLastRightInset = 0
|   mLastTopInset = 75
|   mLastWindowFlags = -2122252032
|   mMenuBackground = null
|   mNavigationColorViewState = com.android.internal.policy.impl.PhoneWindow$ColorViewState [id=0x12ff2c70]
|   mNavigationGuard = null
|   mRootScrollY = 0
|   mShowActionModePopup = null
|   mShowInterpolator = android.view.animation.PathInterpolator [id=0x12ffda60]
|   mStatusColorViewState = com.android.internal.policy.impl.PhoneWindow$ColorViewState [id=0x12ff2c40]
|   mStatusGuard = null
|   mWatchingForMenu = false
|   this$0 = com.android.internal.policy.impl.PhoneWindow [id=0x12db9e00]
|   mForeground = null
|   mForegroundBoundsChanged = true
|   mForegroundGravity = 119
|   mForegroundInPadding = true
|   mForegroundPaddingBottom = 0
|   mForegroundPaddingLeft = 0
|   mForegroundPaddingRight = 0
|   mForegroundPaddingTop = 0
|   mForegroundTintList = null
|   mForegroundTintMode = null
|   mHasForegroundTint = false
|   mHasForegroundTintMode = false
|   mMatchParentChildren = java.util.ArrayList [id=0x12ffd960]
|   mMeasureAllChildren = false
|   mOverlayBounds = android.graphics.Rect [id=0x12ffd940]
|   mSelfBounds = android.graphics.Rect [id=0x12ffd920]
|   mAnimationListener = null
|   mCachePaint = null
|   mChildAcceptsDrag = false
|   mChildCountWithTransientState = 0
|   mChildTransformation = null
|   mChildren = android.view.View[] [id=0x130064c0;length=12]
|   mChildrenCount = 3
|   mCurrentDrag = null
|   mCurrentDragView = null
|   mDisappearingChildren = null
|   mDragNotifiedChildren = null
|   mFirstHoverTarget = null
|   mFirstTouchTarget = null
|   mFocused = android.widget.LinearLayout [id=0x12eac800]
|   mGroupFlags = 2375763
|   mHoveredSelf = false
|   mInvalidateRegion = null
|   mInvalidationTransformation = null
|   mLastTouchDownIndex = 0
|   mLastTouchDownTime = 137539724
|   mLastTouchDownX = 605.0
|   mLastTouchDownY = 1177.0
|   mLayoutAnimationController = null
|   mLayoutCalledWhileSuppressed = false
|   mLayoutMode = 0
|   mLayoutTransitionListener = android.view.ViewGroup$3 [id=0x12fdd850]
|   mLocalPoint = null
|   mNestedScrollAxes = 0
|   mOnHierarchyChangeListener = null
|   mPersistentDrawingCache = 2
|   mPreSortedChildren = null
|   mSuppressLayout = false
|   mTempPoint = float[] [id=0x12c0a220;length=2;size=24]
|   mTransition = null
|   mTransitioningViews = null
|   mVisibilityChangingChildren = null
|   mAccessibilityCursorPosition = -1
|   mAccessibilityDelegate = null
|   mAccessibilityTraversalAfterId = -1
|   mAccessibilityTraversalBeforeId = -1
|   mAccessibilityViewId = -1
|   mAnimator = null
|   mAttachInfo = android.view.View$AttachInfo [id=0x12c4fcc0]
|   mAttributes = null
|   mBackground = android.graphics.drawable.ColorDrawable [id=0x13014f80]
|   mBackgroundRenderNode = android.view.RenderNode [id=0x12c73740]
|   mBackgroundResource = 0
|   mBackgroundSizeChanged = false
|   mBackgroundTint = null
|   mBottom = 1920
|   mCachingFailed = false
|   mClipBounds = null
|   mContentDescription = null
|   mContext = com.couchsurfing.mobile.ui.MainActivity [id=0x12db9c80]
|   mCurrentAnimation = null
|   mDrawableState = null
|   mDrawingCache = null
|   mDrawingCacheBackgroundColor = 0
|   mFloatingTreeObserver = null
|   mGhostView = null
|   mHasPerformedLongPress = false
|   mID = -1
|   mInputEventConsistencyVerifier = null
|   mKeyedTags = null
|   mLabelForId = -1
|   mLastIsOpaque = true
|   mLayerPaint = null
|   mLayerType = 0
|   mLayoutInsets = null
|   mLayoutParams = android.view.WindowManager$LayoutParams [id=0x12f1f7e0]
|   mLeft = 0
|   mLeftPaddingDefined = true
|   mListenerInfo = android.view.View$ListenerInfo [id=0x13109940]
|   mMatchIdPredicate = null
|   mMatchLabelForPredicate = null
|   mMeasureCache = android.util.LongSparseLongArray [id=0x13400120]
|   mMeasuredHeight = 1920
|   mMeasuredWidth = 1080
|   mMinHeight = 0
|   mMinWidth = 0
|   mNestedScrollingParent = null
|   mNextFocusDownId = -1
|   mNextFocusForwardId = -1
|   mNextFocusLeftId = -1
|   mNextFocusRightId = -1
|   mNextFocusUpId = -1
|   mOldHeightMeasureSpec = 1073743744
|   mOldWidthMeasureSpec = 1073742904
|   mOutlineProvider = android.view.ViewOutlineProvider$1 [id=0x6fcd7240]
|   mOverScrollMode = 1
|   mOverlay = null
|   mPaddingBottom = 0
|   mPaddingLeft = 0
|   mPaddingRight = 0
|   mPaddingTop = 0
|   mParent = android.view.ViewRootImpl [id=0x13313400]
|   mPendingCheckForLongPress = null
|   mPendingCheckForTap = null
|   mPerformClick = null
|   mPrivateFlags = 25201976
|   mPrivateFlags2 = 1611867680
|   mPrivateFlags3 = 4
|   mRecreateDisplayList = false
|   mRenderNode = android.view.RenderNode [id=0x12ffd880]
|   mResources = android.content.res.Resources [id=0x12c078e0]
|   mRight = 1080
|   mRightPaddingDefined = true
|   mScrollCache = null
|   mScrollX = 0
|   mScrollY = 0
|   mSendViewScrolledAccessibilityEvent = null
|   mSendViewStateChangedAccessibilityEvent = null
|   mSendingHoverAccessibilityEvents = false
|   mStateListAnimator = null
|   mSystemUiVisibility = 0
|   mTag = null
|   mTempNestedScrollConsumed = null
|   mTop = 0
|   mTouchDelegate = null
|   mTouchSlop = 24
|   mTransformationInfo = android.view.View$TransformationInfo [id=0x1349e7c0]
|   mTransientStateCount = 0
|   mTransitionName = null
|   mUnscaledDrawingCache = null
|   mUnsetPressedState = null
|   mUserPaddingBottom = 0
|   mUserPaddingEnd = -2147483648
|   mUserPaddingLeft = 0
|   mUserPaddingLeftInitial = 0
|   mUserPaddingRight = 0
|   mUserPaddingRightInitial = 0
|   mUserPaddingStart = -2147483648
|   mVerticalScrollFactor = 0.0
|   mVerticalScrollbarPosition = 0
|   mViewFlags = 402655360
|   mWindowAttachCount = 1
* Instance of android.view.View$AttachInfo
|   mAccessibilityFetchFlags = 0
|   mAccessibilityFocusDrawable = null
|   mAccessibilityWindowId = 2147483647
|   mApplicationScale = 1.0
|   mCanvas = null
|   mContentInsets = android.graphics.Rect [id=0x13364ee0]
|   mDebugLayout = false
|   mDisabledSystemUiVisibility = 0
|   mDisplay = android.view.Display [id=0x12f75b50]
|   mDisplayState = 2
|   mDrawingTime = 137551407
|   mForceReportNewAttributes = false
|   mGivenInternalInsets = android.view.ViewTreeObserver$InternalInsetsInfo [id=0x13364f40]
|   mGlobalSystemUiVisibility = 0
|   mHandler = android.view.ViewRootImpl$ViewRootHandler [id=0x13364d00]
|   mHardwareAccelerated = true
|   mHardwareAccelerationRequested = true
|   mHardwareRenderer = android.view.ThreadedRenderer [id=0x13323dc0]
|   mHasNonEmptyGivenInternalInsets = false
|   mHasSystemUiListeners = true
|   mHasWindowFocus = true
|   mHighContrastText = false
|   mIWindowId = null
|   mIgnoreDirtyState = false
|   mInTouchMode = true
|   mInvalidateChildLocation = int[] [id=0x13370060;length=2;size=24]
|   mKeepScreenOn = false
|   mKeyDispatchState = android.view.KeyEvent$DispatcherState [id=0x13364fc0]
|   mOverscanInsets = android.graphics.Rect [id=0x13364ec0]
|   mOverscanRequested = false
|   mPanelParentWindowToken = null
|   mPendingAnimatingRenderNodes = null
|   mPoint = android.graphics.Point [id=0x133582f0]
|   mRecomputeGlobalAttributes = false
|   mRootCallbacks = android.view.ViewRootImpl [id=0x13313400]
|   mRootView = com.android.internal.policy.impl.PhoneWindow$DecorView [id=0x12eac000]
|   mScalingRequired = false
|   mScrollContainers = java.util.ArrayList [id=0x13364fa0]
|   mSession = android.view.IWindowSession$Stub$Proxy [id=0x13358290]
|   mSetIgnoreDirtyState = true
|   mStableInsets = android.graphics.Rect [id=0x13364f20]
|   mSystemUiVisibility = 0
|   mTempArrayList = java.util.ArrayList [id=0x133701a0]
|   mTmpInvalRect = android.graphics.Rect [id=0x133700c0]
|   mTmpLocation = int[] [id=0x13370080;length=2;size=24]
|   mTmpMatrix = android.graphics.Matrix [id=0x133582d0]
|   mTmpOutline = android.graphics.Outline [id=0x13370180]
|   mTmpRectList = java.util.ArrayList [id=0x13370120]
|   mTmpTransformLocation = float[] [id=0x133700a0;length=2;size=24]
|   mTmpTransformRect = android.graphics.RectF [id=0x133700e0]
|   mTmpTransformRect1 = android.graphics.RectF [id=0x13370100]
|   mTmpTransformation = android.view.animation.Transformation [id=0x13370140]
|   mTransparentLocation = int[] [id=0x13370040;length=2;size=24]
|   mTreeObserver = android.view.ViewTreeObserver [id=0x133656c0]
|   mTurnOffWindowResizeAnim = false
|   mUnbufferedDispatchRequested = false
|   mUse32BitDrawingCache = true
|   mViewRequestingLayout = null
|   mViewRootImpl = android.view.ViewRootImpl [id=0x13313400]
|   mViewScrollChanged = false
|   mViewVisibilityChanged = false
|   mVisibleInsets = android.graphics.Rect [id=0x13364f00]
|   mWindow = android.view.ViewRootImpl$W [id=0x13364e80]
|   mWindowId = null
|   mWindowLeft = 0
|   mWindowToken = android.view.ViewRootImpl$W [id=0x13364e80]
|   mWindowTop = 0
|   mWindowVisibility = 0
* Instance of android.view.ViewTreeObserver
|   mAlive = true
|   mOnComputeInternalInsetsListeners = null
|   mOnDrawListeners = null
|   mOnEnterAnimationCompleteListeners = null
|   mOnGlobalFocusListeners = null
|   mOnGlobalLayoutListeners = android.view.ViewTreeObserver$CopyOnWriteArray [id=0x1315a300]
|   mOnPreDrawListeners = android.view.ViewTreeObserver$CopyOnWriteArray [id=0x13345760]
|   mOnScrollChangedListeners = android.view.ViewTreeObserver$CopyOnWriteArray [id=0x12fd3220]
|   mOnTouchModeChangeListeners = java.util.concurrent.CopyOnWriteArrayList [id=0x133a1420]
|   mOnWindowAttachListeners = null
|   mOnWindowFocusListeners = null
|   mOnWindowShownListeners = null
|   mWindowShown = false
* Instance of android.view.ViewTreeObserver$CopyOnWriteArray
|   mAccess = android.view.ViewTreeObserver$CopyOnWriteArray$Access [id=0x12fa1960]
|   mData = java.util.ArrayList [id=0x12fd3240]
|   mDataCopy = null
|   mStart = false
* Instance of java.util.ArrayList
|   static $staticOverhead = byte[] [id=0x6fcffb29;length=16;size=32]
|   static MIN_CAPACITY_INCREMENT = 12
|   static serialVersionUID = 8683452581122892189
|   array = java.lang.Object[] [id=0x13094a40;length=12]
|   size = 1
|   modCount = 1
* Array of java.lang.Object[]
|   [0] = com.couchsurfing.mobile.ui.events.detail.EventDetailsView$1 [id=0x12fa1950]
|   [1] = null
|   [2] = null
|   [3] = null
|   [4] = null
|   [5] = null
|   [6] = null
|   [7] = null
|   [8] = null
|   [9] = null
|   [10] = null
|   [ 

Source: (StackOverflow)

Cannot find symbol class AndroidExcludedRefs, DisplayLeakService,

We are declaring our leak-canary dependencies as stated on the project's Github page.

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'

So far, things are working fine. Now we started to exclude a known leak like that:

ExcludedRefs.Builder excludedRefsBuilder = AndroidExcludedRefs.createAppDefaults();
excludedRefsBuilder.staticField("com.google.android.chimera.container.a", "a");
refWatcher = LeakCanary.install(app, DisplayLeakService.class, excludedRefsBuilder.build());

Now when we switch to the release build type, classes like AndroidExcludedRefs, DisplayLeakService and ExcludedRefs are not found anymore, as the "no-op" dependency doesn't include them.

What's the best way to handle this?


Source: (StackOverflow)

Android Chrome Facebook webview memory leak using Leakcanary

Randomly I'm having this leaks after performing login with Facebook Webview

enter image description here enter image description here enter image description here

I've found this (the only mention to com.android.org.chromium):

AW_RESOURCE__SRESOURCES(SAMSUNG.equals(MANUFACTURER) && SDK_INT == KITKAT) {
    @Override void add(ExcludedRefs.Builder excluded) {
      // AwResource#setResources() is called with resources that hold a reference to the
      // activity context (instead of the application context) and doesn't clear it.
      // Not sure what's going on there, input welcome.
      excluded.staticField("com.android.org.chromium.android_webview.AwResource", "sResources");
    }
  },

Inside this class AndroidExcludedRefs.java

This class is a work in progress. You can help by reporting leak traces that seem to be caused by the Android SDK, here: https://github.com/square/leakcanary/issues/new

But I'm not using Samsung so I'm still having this leak.
Said that, is this leak a known issue? Can it be ignored?

UPDATE: I was using Facebook SDK v3.19, I've updated to 4.3 but the problem remains: enter image description here


Source: (StackOverflow)

LeakCanary investigation : com.motorola.pixelpipe.PixelPipeTarget.mContext

With LeakMemory I constantly have a report on com.motorola.pixelpipe.PixelPipeTarget.mContext. I have no idea what this is. Anyone have the same report ?

Using MotoX 2014 with 5.0

LeakCanary  D  In net.ebt.appswitch:0.8.3.394:3940002.
            D  * net.ebt.appswitch.activity.AppSwapActivity has leaked:
            D  * GC ROOT com.motorola.pixelpipe.PixelPipeTarget.mContext
            D  * leaks net.ebt.appswitch.activity.AppSwapActivity instance
            D  * Reference Key: 41a91591-b7f4-4a12-b077-46b35a53f9cf
            D  * Device: motorola motorola XT1095 victara_tmo
            D  * Android Version: 5.0 API: 21
            D  * Durations: watch=5028ms, gc=187ms, heap dump=1626ms, analysis=26686ms

Thanks


Source: (StackOverflow)

Memory Leak on DeathMonitor using LeakCanary

I use LeakCanary and unfortunately got a leak and here is the logcat:

In com.appturbo.appoftheday2015:2.09.2:222.
* com.appturbo.appturbo.ui.HomeActivity has leaked:
* GC ROOT com.android.internal.util.AsyncChannel$DeathMonitor.this$0
* references com.android.internal.util.AsyncChannel.mSrcContext
* leaks com.appturbo.appturbo.ui.HomeActivity instance

* Reference Key: e049c2ed-6784-4850-b794-20fa96c13dcf
* Device: motorola google Nexus 6 shamu
* Android Version: 5.1 API: 22
* Durations: watch=5176ms, gc=228ms, heap dump=4974ms, analysis=29320ms

Does some of you have already seen a leek like that? Any idea? This leak appear after:

  • Changing the Ressource Configuration to switch the language
  • Finish the activity
  • Restart the activity

Source: (StackOverflow)

MapView v2 keeping Context around

When using the MapView from the latest google maps API, I am getting a memory leak because MapView is holding onto my activity.

I used Leak Canary and have this trace


D/LeakCanary﹕ * GC ROOT com.google.android.gms.location.internal.t.a

D/LeakCanary﹕ * references com.google.android.gms.location.internal.s.a

D/LeakCanary﹕ * references com.google.maps.api.android.lib6.d.v.c

D/LeakCanary﹕ * references com.google.maps.api.android.lib6.d.aj.b

D/LeakCanary﹕ * references com.google.maps.api.android.lib6.gmm6.c.p.a

D/LeakCanary﹕ * references com.google.maps.api.android.lib6.gmm6.c.y.mParent

D/LeakCanary﹕ * references android.widget.FrameLayout.mParent

D/LeakCanary﹕ * references com.google.android.gms.maps.MapView.mContext

D/LeakCanary﹕ * leaks com.myapp.activities.main.AttractionDetailActivity instance


Has anyone seen this before?


Source: (StackOverflow)

LeakCanary spots Android WebView memory leak

I've been using the a tool leakcanary to spot memory leakages in my application. It seems my WebViewActivity leaks everytime.

I created a simple application to test the leakages. I start a Activity with a WebView inside xml layout file/inflate with activity context. Js off. Everything default expect a simple webViewClient keeping redirection within the WebView. It leaks every time.

I've done plenty of research, the only way to prevent this is start WebViewActivity with another process and kill it inside onDestroy. But this method has its own disadvantages.

The leak happens every time on all my devices running 5.0+, haven't checked with 4.3 and below.

The leak info is pasted below:

In com.example.webviewmemoryleaktest:1.0:1. * com.example.webviewmemoryleaktest.WebViewActivity has leaked: * GC ROOT android.os.ResultReceiver$MyResultReceiver.this$0 * references org.chromium.content.browser.ContentViewCore$2$1.this$1 (anonymous class extends android.os.ResultReceiver) * references org.chromium.content.browser.ContentViewCore$2.this$0 * references org.chromium.content.browser.ContentViewCore.mContext * references com.android.webview.chromium.ResourcesContextWrapperFactory$WebViewContextWrapper.mBase * leaks com.example.webviewmemoryleaktest.WebViewActivity instance

  • Reference Key: 9a0346cf-6ad9-4b07-9329-a975d8fa3cbe
  • Device: LGE google Nexus 4 occam
  • Android Version: 5.1 API: 22
  • Durations: watch=5139ms, gc=188ms, heap dump=2822ms, analysis=30918ms

Appreciate if anyone could help. Thanks!


Source: (StackOverflow)

Why is this a memory leak

I came across a library for memory leak detection in Android (Java) called LeakCanary but cannot understand the example where they leak the memory. Could anybody please explain how and why the code shown in their example is a memory leak.

class Cat {
}
class Box {
  Cat hiddenCat;
}
class Docker {
  static Box container;
}

// ...

Box box = new Box();
Cat schrodingerCat = new Cat();
box.hiddenCat = schrodingerCat;
Docker.container = box;

and then they watch the variable schrodingerCat for leaks which gives a leak shown as follows (which I dont know how to relate to the above code).

* GC ROOT static Docker.container
* references Box.hiddenCat
* leaks Cat instance

Any help with the explanation of the leak and how the detection relates to it would be very helpful. Also some good articles for beginners would be nice.

Thanks!


Source: (StackOverflow)

Square LeakCanary Cannot find symbol

Here is the screenshot

build.gradle has been configured as per github insturctions.LeakCanary class doesn't seem to be included.

 dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
 }

enter image description here

analyzer and watcher packages has just 1 single class file in it.


Source: (StackOverflow)

Memory leak in Fragment

I am using the LeakCanary library to monitor memory leaks in my app. I received this memory leak and not sure how to track down what is causing it.

05-09 09:32:14.731  28497-31220/? D/LeakCanary﹕ In com.etiennelawlor.minesweeper:0.0.21:21.
    * com.etiennelawlor.minesweeper.fragments.MinesweeperFragment has leaked:
    * GC ROOT com.google.android.gms.games.internal.GamesClientImpl$PopupLocationInfoBinderCallbacks.zzahO
    * references com.google.android.gms.games.internal.PopupManager$PopupManagerHCMR1.zzajo
    * references com.google.android.gms.games.internal.GamesClientImpl.mContext
    * references com.etiennelawlor.minesweeper.activities.MinesweeperActivity.mFragments
    * references android.app.FragmentManagerImpl.mAdded
    * references java.util.ArrayList.array
    * references array java.lang.Object[].[0]
    * leaks com.etiennelawlor.minesweeper.fragments.MinesweeperFragment instance
    * Reference Key: 2f367393-6dfd-4797-8d85-7ac52c431d07
    * Device: LGE google Nexus 5 hammerhead
    * Android Version: 5.1 API: 22
    * Durations: watch=5015ms, gc=141ms, heap dump=1978ms, analysis=23484ms

This is my repo : https://github.com/lawloretienne/Minesweeper

This seems to be an elusive one. I set up an Interface to communicate between a Fragment and an Activity. I set this mCoordinator Interface variable up in onAttach() then I realized I was not nulling it out in onDetach(). I fixed that issue but still am getting a memory leak. Any ideas?

Update

I disabled the Fragment leak watching, and I still get a notification about the activity leaking with the following leak trace :

05-09 17:07:33.074  12934-14824/? D/LeakCanary﹕ In com.etiennelawlor.minesweeper:0.0.21:21.
    * com.etiennelawlor.minesweeper.activities.MinesweeperActivity has leaked:
    * GC ROOT com.google.android.gms.games.internal.GamesClientImpl$PopupLocationInfoBinderCallbacks.zzahO
    * references com.google.android.gms.games.internal.PopupManager$PopupManagerHCMR1.zzajo
    * references com.google.android.gms.games.internal.GamesClientImpl.mContext
    * leaks com.etiennelawlor.minesweeper.activities.MinesweeperActivity instance
    * Reference Key: f4d06830-0e16-43a2-9750-7e2cb77ae24d
    * Device: LGE google Nexus 5 hammerhead
    * Android Version: 5.1 API: 22
    * Durations: watch=5016ms, gc=164ms, heap dump=3430ms, analysis=39535ms

Source: (StackOverflow)