Android泄漏金丝雀日志
Posted
技术标签:
【中文标题】Android泄漏金丝雀日志【英文标题】:Android Leak Canary Log 【发布时间】:2015-11-14 12:47:13 【问题描述】:我正在使用 Leaky Canary 来检测我的应用程序中的内存泄漏。虽然在此之前我能够摆脱 2-3 个问题,但我无法从该日志中找出泄漏的位置
11-14 18:05:05.330 32099-3554/? D/LeakCanary: In com.prism.prism:1.1:2.
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * com.prism.prism.RatePicActivity_ has leaked:
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * GC ROOT android.database.ContentObserver$Transport.mContentObserver
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * references android.app.Activity$SettingsObserver.this$0
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * leaks com.prism.prism.RatePicActivity_ instance
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Reference Key: 29bcc62a-b7e2-4d80-8cda-be2f841f19aa
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Device: samsung samsung GT-I9300 m0xx
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Android Version: 4.4.4 API: 19 LeakCanary: 1.3.1
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Durations: watch=5024ms, gc=176ms, heap dump=1129ms, analysis=12787ms
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Details:
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Instance of android.database.ContentObserver$Transport
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mContentObserver = android.app.Activity$SettingsObserver [id=0x41b22d00]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mDescriptor = java.lang.String [id=0x41913c70]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mOwner = android.database.ContentObserver$Transport [id=0x41b1a878]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mObject = 1570915608
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Instance of android.app.Activity$SettingsObserver
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | this$0 = com.prism.prism.RatePicActivity_ [id=0x41ba5aa0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mHandler = android.os.Handler [id=0x41c45f78]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mLock = java.lang.Object [id=0x41c7c220]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mTransport = android.database.ContentObserver$Transport [id=0x41b1a878]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * Instance of com.prism.prism.RatePicActivity_
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | onViewChangedNotifier_ = org.androidannotations.api.view.OnViewChangedNotifier [id=0x41cceb68]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | application = com.prism.prism.MyApplication_ [id=0x41b26fe0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | backgroundImageView = android.support.v7.widget.AppCompatImageView [id=0x41ba1960]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | fragment_container = android.widget.FrameLayout [id=0x41b6f098]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mDelegate = android.support.v7.app.AppCompatDelegateImplV14 [id=0x4226a548]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mMediaController = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mFragments = android.support.v4.app.FragmentController [id=0x41cd05c0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mHandler = android.support.v4.app.FragmentActivity$1 [id=0x41c63520]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mCreated = true
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mOptionsMenuInvalidated = false
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mReallyStopped = true
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mRequestedPermissionsFromFragment = false
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mResumed = false
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mRetaining = false
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mStopped = true
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mActionBar = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mActivityInfo = android.content.pm.ActivityInfo [id=0x41c6ab08]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mAllLoaderManagers = android.util.ArrayMap [id=0x41cab818]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mApplication = com.prism.prism.MyApplication_ [id=0x41b26fe0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mWindowManager = android.view.WindowManagerImpl [id=0x41c48e60]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mWindow = com.android.internal.policy.impl.PhoneWindow [id=0x41b966a0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mUiThread = java.lang.Thread [id=0x417e1d80]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mTranslucentCallback = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mComponent = android.content.ComponentName [id=0x41c76c08]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mToken = android.os.BinderProxy [id=0x41c730f8]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mContainer = android.app.Activity$1 [id=0x41cffe98]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mCurrentConfig = android.content.res.Configuration [id=0x41df0360]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mDecor = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mTitle = java.lang.String [id=0x41b66db8]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mDefaultKeySsb = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mSettingsObserver = android.app.Activity$SettingsObserver [id=0x41b22d00]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mSearchManager = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mEmbeddedID = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mResultData = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mParent = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mFragments = android.app.FragmentManagerImpl [id=0x41ed3590]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mHandler = android.os.Handler [id=0x41c45f78]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mMenuInflater = null
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mImmerseModeRunnable = android.app.Activity$3 [id=0x41cebb80]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mInstanceTracker = android.os.StrictMode$InstanceTracker [id=0x41cf0dc0]
11-14 18:05:05.330 32099-3554/? D/LeakCanary: | mInstrumentation = android.app.Instrumentation [id=0x41b26818]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mIntent = android.content.Intent [id=0x41b19e40]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mLastNonConfigurationInstances = null
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mLoaderManager = null
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mManagedDialogs = null
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mMainThread = android.app.ActivityThread [id=0x41b16958]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mManagedCursors = java.util.ArrayList [id=0x41c6d948]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mLoadersStarted = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mIdent = 1103360840
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mFinished = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mResultCode = 0
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mEnableDefaultActionBarUp = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mResumed = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mDoReportFullyDrawn = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mDestroyed = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mStartedActivity = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mStopped = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mTemporaryPause = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mDefaultKeyMode = 0
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mTitleColor = 0
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mTitleReady = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mConfigChangeFlags = 0
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mCheckedForLoaderManager = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mChangingConfigurations = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mVisibleFromClient = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mVisibleFromServer = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mChangeCanvasToTranslucent = false
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mWindowAdded = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mCalled = true
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mBase = uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper [id=0x41c522b8]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mInflater = uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater [id=0x41df9618]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mOverrideConfiguration = null
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mResources = android.content.res.XResources [id=0x41b22d80]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mTheme = android.content.res.Resources$Theme [id=0x41c48c10]
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mThemeResource = 2131492994
11-14 18:05:05.335 32099-3554/? D/LeakCanary: | mBase = uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper [id=0x41c522b8]
11-14 18:05:05.335 32099-3554/? E/LeakCanary: Leak result dropped because we already store 7 leak traces.
在这种情况下,我无法确定内存泄漏发生在哪里。有人可以指出如何识别它吗?
【问题讨论】:
【参考方案1】:11-14 18:05:05.330 32099-3554/? D/LeakCanary: * com.prism.prism.RatePicActivity_ has leaked:
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * GC ROOT android.database.ContentObserver$Transport.mContentObserver
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * references android.app.Activity$SettingsObserver.this$0
11-14 18:05:05.330 32099-3554/? D/LeakCanary: * leaks com.prism.prism.RatePicActivity_ instance
查看上面日志中的第三行,系统中某处有对设置观察者的引用,而该引用又包含对活动的引用。
所以很可能您没有取消注册您的内容观察者SettingsObserver
。请执行以下操作:
getContentResolver().unregisterContentObserver(settingsObserverReference);
这是ContentResolver#unregisterContentObserver的文档
【讨论】:
【参考方案2】:@shubham-chaudhary,对于这种情况?
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: * Instance of android.database.ContentObserver$Transport
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mContentObserver = com.android.internal.policy.impl.PhoneWindow$SettingsObserver [id=0x130efea0]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mDescriptor = java.lang.String [id=0x7016e998]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mObject = -1185785128
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mOwner = android.database.ContentObserver$Transport [id=0x13172320]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: * Instance of com.android.internal.policy.impl.PhoneWindow$SettingsObserver
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | this$0 = com.android.internal.policy.impl.PhoneWindow [id=0x12eabf80]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mHandler = android.os.Handler [id=0x130efec0]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mLock = java.lang.Object [id=0x130f1240]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: | mTransport = android.database.ContentObserver$Transport [id=0x13172320]
11-19 11:22:09.513 9335-10345/lar21.pontotel D/LeakCanary: * Instance of com.android.internal.policy.impl.PhoneWindow
【讨论】:
看起来像 android 内部的泄漏。我也面临与 TextSpan 等类似的泄漏。如果您找不到任何类似的问题,请打开一个带有跟踪的问题,有人可能会指出您的解决方法/解决方案。以上是关于Android泄漏金丝雀日志的主要内容,如果未能解决你的问题,请参考以下文章