square / leakcanary Goto Github PK
View Code? Open in Web Editor NEWA memory leak detection library for Android.
Home Page: https://square.github.io/leakcanary
License: Apache License 2.0
A memory leak detection library for Android.
Home Page: https://square.github.io/leakcanary
License: Apache License 2.0
I notice this crash coming up a lot. I get a message that my app has crashed but it remains running.
FATAL EXCEPTION: IntentService[HeapAnalyzerService]
java.lang.ArrayIndexOutOfBoundsException: length=335831; index=-54100
at org.eclipse.mat.parser.index.IndexWriter$IntArray1NWriter.set(IndexWriter.java:608)
at org.eclipse.mat.parser.index.IndexWriter$IntArray1NWriter.log(IndexWriter.java:590)
at org.eclipse.mat.hprof.HprofParserHandlerImpl.addObject(HprofParserHandlerImpl.java:442)
at org.eclipse.mat.hprof.Pass2Parser.readInstanceDump(Pass2Parser.java:270)
at org.eclipse.mat.hprof.Pass2Parser.readDumpSegments(Pass2Parser.java:158)
at org.eclipse.mat.hprof.Pass2Parser.read(Pass2Parser.java:90)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:80)
at org.eclipse.mat.parser.internal.SnapshotFactory.parse(SnapshotFactory.java:193)
at org.eclipse.mat.parser.internal.SnapshotFactory.openSnapshot(SnapshotFactory.java:106)
at com.squareup.leakcanary.HeapAnalyzer.openSnapshot(HeapAnalyzer.java:134)
at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:87)
at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:61)
Looking at the code in SharedActionProvider:
private void setActivityChooserPolicyIfNeeded() {
if (mOnShareTargetSelectedListener == null) {
return;
}
if (mOnChooseActivityListener == null) {
mOnChooseActivityListener = new ShareActivityChooserModelPolicy();
}
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
dataModel.setOnChooseActivityListener(mOnChooseActivityListener);
}
This creates an inner class, which holds a reference to the context. That is registered with the dataModel which is in sDataModelRegistry.
D/LeakCanary(18907): * no.finn.android.ui.homepage.HomeActivity has leaked:
D/LeakCanary(18907): * GC ROOT static android.widget.ActivityChooserModel.sDataModelRegistry
D/LeakCanary(18907): * references java.util.HashMap.table
D/LeakCanary(18907): * references array java.util.HashMap$HashMapEntry[].[1]
D/LeakCanary(18907): * references java.util.HashMap$HashMapEntry.value
D/LeakCanary(18907): * references android.widget.ActivityChooserModel.mActivityChoserModelPolicy
D/LeakCanary(18907): * references android.widget.ShareActionProvider$ShareAcitivityChooserModelPolicy.this$0
D/LeakCanary(18907): * references android.widget.ShareActionProvider.mContext
D/LeakCanary(18907): * references android.view.ContextThemeWrapper.mBase
D/LeakCanary(18907): * leaks no.finn.android.ui.homepage.HomeActivity instance
We use the following hack to avoid the problem:
ActivityChooserModel dataModel = ActivityChooserModel.get(context, ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME);
dataModel.setOnChooseActivityListener(new ActivityChooserModel.OnChooseActivityListener() {
@Override
public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
return false;
}
});
NB : Sending in null on setOnChooseActivityListener will work on SOME sdk versions.
In com.example.android_alpha.app:1.0:1.
* com.kiwiwearables.kiwilib.KiwiService has leaked:
* GC ROOT android.app.ActivityThread$ApplicationThread.this$0
* references android.app.ActivityThread.mServices
* references android.util.ArrayMap.mArray
* references array java.lang.Object[].[3]
* leaks com.kiwiwearables.kiwilib.KiwiService instance
* Reference Key: 599ac81b-d683-4f07-8a83-e840119982ed
* Device: LGE google Nexus 5 hammerhead
* Android Version: 5.1 API: 22
* Durations: watch=5639ms, gc=208ms, heap dump=3528ms, analysis=37676ms
I am not sure why this happen to me. But, I faced it and still.
Also, whenever I got this log, the main thread stopped 300ms~1000ms.
I/art﹕ hprof: heap dump "/data/data/com.app/files/suspected_leak_heapdump.hprof" starting...
on Galaxy S6
I got a couple of similar reports like this (real device)
* de.busliniensuche.android.MainActivity has leaked:
* GC ROOT thread android.os.HandlerThread.<Java Local> (named 'Filter')
* references android.os.MessageQueue.mMessages
* references android.os.Message.target
* references android.widget.Filter$RequestHandler.this$0
* references de.busliniensuche.android.view.StationSearchListAdapter$StationSearchFilter.stationSearchListAdapter
* references de.busliniensuche.android.view.StationSearchListAdapter.animListView
* references de.busliniensuche.android.view.AnimationListView.mContext
* leaks de.busliniensuche.android.MainActivity instance
* Reference Key: ae18be53-5a9d-4358-a7d5-479f38fa6c90
* Device: LGE google Nexus 4 occam
* Android Version: 5.1.1 API: 22
* Durations: watch=5194ms, gc=277ms, heap dump=8276ms, analysis=42454ms
or this (Genymotion)
* de.busliniensuche.android.StationSearchFragment has leaked:
* GC ROOT thread android.os.HandlerThread.<Java Local> (named 'Filter')
* references android.os.MessageQueue.mMessages
* references android.os.Message.target
* references android.widget.Filter$RequestHandler.this$0
* references de.busliniensuche.android.view.StationSearchListAdapter$StationSearchFilter.stationSearchListAdapter
* references de.busliniensuche.android.view.StationSearchListAdapter.listener
* leaks de.busliniensuche.android.StationSearchFragment instance
* Reference Key: f4768f4c-452d-40cc-936a-efa2282dda06
* Device: Genymotion generic Google Nexus 4 - 5.1.0 - API 22 - 768x1280 vbox86p
* Android Version: 5.1 API: 22
* Durations: watch=5035ms, gc=127ms, heap dump=574ms, analysis=7063ms
As far as I can tell, the root issue is the leak of StationSearchFilter
which holds a reference to the adapter which in turn leaks all kinds of stuff.
Now, I can't figur out what exactly is causing the leak. It seems the HandlerThread that is started in Filter.filter isn't properly closed and therefore leaks a message.
It's embarrassed to say that I got a runtime problem which looks like this:
Process: com.example.leakcanary, PID: 5644
java.lang.RuntimeException: Unable to create application com.example.leakcanary.ExampleApplication: java.lang.IllegalArgumentException: Component class com.squareup.leakcanary.internal.DisplayLeakActivity does not exist in com.example.leakcanary
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4375)
at android.app.ActivityThread.access$1500(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5047)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Component class com.squareup.leakcanary.internal.DisplayLeakActivity does not exist in com.example.leakcanary
at android.os.Parcel.readException(Parcel.java:1476)
at android.os.Parcel.readException(Parcel.java:1426)
at android.content.pm.IPackageManager$Stub$Proxy.setComponentEnabledSetting(IPackageManager.java:2943)
at android.app.ApplicationPackageManager.setComponentEnabledSetting(ApplicationPackageManager.java:1285)
at com.squareup.leakcanary.LeakCanary.setEnabled(LeakCanary.java:195)
at com.squareup.leakcanary.LeakCanary.enableDisplayLeakActivity(LeakCanary.java:75)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:55)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
at com.example.leakcanary.ExampleApplication.onCreate(ExampleApplication.java:34)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4372)
at android.app.ActivityThread.access$1500(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5047)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Could you give me some advice? Thank you.
A few links that we could include:
Replace this:
* Android Version: 5.0.2 API: 21
with this:
Android Version: 5.0.2 API: 21 LeakCanary: 1.3.1
Android's Strict mode detected a disk write with the following stack trace:
05-12 07:48:03.093 9989-9989/? D/StrictMode﹕ StrictMode policy violation; ~duration=98 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=341 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at libcore.io.BlockGuardOs.mkdir(BlockGuardOs.java:172)
at java.io.File.mkdirErrno(File.java:874)
at java.io.File.mkdirs(File.java:898)
at java.io.File.mkdirs(File.java:892)
at com.android.server.pm.Settings.writePackageRestrictionsLPr(Settings.java:1277)
at com.android.server.pm.PackageManagerService.setEnabledSetting(PackageManagerService.java:12201)
at com.android.server.pm.PackageManagerService.setComponentEnabledSetting(PackageManagerService.java:12109)
at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:1219)
at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:1862)
at android.os.Binder.execTransact(Binder.java:446)
# via Binder call with stack:
android.os.StrictMode$LogStackTrace
at android.os.StrictMode.readAndHandleBinderCallViolations(StrictMode.java:1717)
at android.os.Parcel.readExceptionCode(Parcel.java:1527)
at android.os.Parcel.readException(Parcel.java:1496)
at android.content.pm.IPackageManager$Stub$Proxy.setComponentEnabledSetting(IPackageManager.java:3394)
at android.app.ApplicationPackageManager.setComponentEnabledSetting(ApplicationPackageManager.java:1489)
at com.squareup.leakcanary.LeakCanary.setEnabled(LeakCanary.java:195)
at com.squareup.leakcanary.LeakCanary.enableDisplayLeakActivity(LeakCanary.java:75)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:55)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
at various.App.onCreate(App.java:44)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1012)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4553)
at android.app.ActivityThread.access$1500(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
org.lakedaemon.android.activity.RxWordActivity has leaked:
* GC ROOT static android.media.AudioManager.mContext_static
* references android.app.ContextImpl.mOuterContext
* leaks org.lakedaemon.android.activity.RxWordActivity instance
* Reference Key: 4ab479ea-2267-4b99-b384-767157abf988
* Device: samsung samsung GT-I9305 m3xx
* Android Version: 4.4.4 API: 19
* Durations: watch=5021ms, gc=161ms, heap dump=695ms, analysis=24326ms
I'll post a heap dump as soon as I figure out where to find it/how to do it
I'm keep getting this error:
05-12 06:37:46.779 16807-16836/? E/AndroidRuntime﹕ FATAL EXCEPTION: IntentService[HeapAnalyzerService]
java.lang.StackOverflowError
at java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:425)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1566)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeNewArray(ObjectOutputStream.java:1205)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1662)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.util.ArrayList.writeObject(ArrayList.java:648)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.util.ArrayList.writeObject(ArrayList.java:648)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.util.ArrayList.writeObject(ArrayList.java:648)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(
I have it installed in Application and added watcher for Fragment.onDestroy.
05-09 12:56:56.174 18379-19786/com.b.kD/LeakCanary﹕ In com.b.k:1.4.4.7:57.
* com.b.k.Add_User has leaked:
* GC ROOT android.app.LoadedApk$ServiceDispatcher$DeathMonitor.this$0
* references android.app.LoadedApk$ServiceDispatcher.mConnection
* references com.android.vending.billing.util.IabHelper$1.val$listener (anonymous class implements android.content.ServiceConnection)
* references com.b.k.Add_User$5.this$0 (anonymous class implements com.android.vending.billing.util.IabHelper$OnIabSetupFinishedListener)
* leaks com.b.k.Add_User instance
* Reference Key: c06d2f1f-b1ad-4419-b17b-d9d0e0eb10f7
* Device: Genymotion generic Google Nexus 4 - 4.2.2 - API 17 - 768x1280 vbox86p
* Android Version: 4.2.2 API: 17
* Durations: watch=5006ms, gc=107ms, heap dump=153ms, analysis=4607ms
Just want to say, this library is a godsend, the problem i'm having however is actually discerning the location/cause of the leak? Which line should i be focussing on in order to find the culprit here?
It almost looks as if its coming from Google's IAB helpers?
Thanks!
Leak is the following one :
In com.jeuxvideo:3.0-debug:56.
I think this happened after I came back from sharing a content.
I have following leak on vanilla 5.1 on Nexus 5.
In com.wheely.wheely.dev:5.1.3:1014510.
* com.wheely.app.ui.home.profile.CardActivity has leaked:
* GC ROOT android.view.textservice.SpellCheckerSession$SpellCheckerSessionListenerImpl.mHandler
* references android.view.textservice.SpellCheckerSession$1.this$0 (anonymous class extends android.os.Handler)
* references android.view.textservice.SpellCheckerSession.mSpellCheckerSessionListener
* references android.widget.SpellChecker.mTextView
* references com.paymentkit.views.InterceptEditText.mContext
* leaks com.wheely.app.ui.home.profile.CardActivity instance
D/LeakCanary( 7557):
* Reference Key: 3d9a5a01-4d51-472e-a459-717c21e1c7d1
* Device: LGE google Nexus 5 hammerhead
* Android Version: 5.1 API: 22
* Durations: watch=5027ms, gc=158ms, heap dump=2430ms, analysis=25573ms
Samsung Galaxy S Edge. Same to the one defined here:
https://github.com/square/leakcanary/blob/master/library/leakcanary-android/src/main/java/com/squareup/leakcanary/AndroidExcludedRefs.java
but with different variable name, here is the trace:
com.opensooq.OpenSooq.ui.login.RegistrationActivity has leaked:
* GC ROOT android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue
* references android.os.MessageQueue.mMessages
* references android.os.Message.next
* references android.os.Message.callback
* references android.widget.Editor$Blink.this$0
* references android.widget.Editor.mTextView
* references android.support.v7.widget.AppCompatAutoCompleteTextView.mClipboardExManager
* references android.sec.clipboard.ClipboardExManager.mClipboardUIManager
* references android.sec.clipboard.ClipboardUIManager.mContext
* leaks com.opensooq.OpenSooq.ui.login.RegistrationActivity instance* Reference Key: 898151f2-829a-4242-b074-a53cc88cce8d
* Device: samsung samsung SM-G925F zeroltexx
* Android Version: 5.0.2 API: 21
* Durations: watch=5015ms, gc=167ms, heap dump=2782ms, analysis=28642ms
Permission denied for the attachment
I just see leak log,can show me like screenshot?
The leak trace string representation is nice because it makes it easy to point to the problem and identify a few key references that should not exist.
However, when trying to understand why a reference still exists, we sometimes need more info from the heap dump. It's fairly easy to do so in MAT.
However, it might be useful to create a shorcut by providing the state information (instance fields) for each of the reference in the chain. ie for each of those fields, give the type & memory address.
That would be something separate from the leak trace string, ie available as fields in it and maybe through a toDetailedString()
method. We might want leakInfo()
to include that as well.
Each time there is an OOM that caused the app to crash, I'd like that this additional information would be added to the report that's sent to the Play Store.
Is it possible?
Also, I've noticed that there are multiple steps that occur when there is OOM. Are they fast enough for this? If not, is there a way to make it do it all work faster just for this task?
I think that for my use-case, using the Play Store for OOM crash reporting is enough.
I add as the README shows:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
But it results in:
Error:(73, 20) Failed to resolve: com.squareup.leakcanary:leakcanary-android-no-op:1.3
Error:(72, 18) Failed to resolve: com.squareup.leakcanary:leakcanary-android:1.3
Repository configuration:
allprojects {
repositories {
jcenter()
}
}
Thank you!
Looks like #30 broke excluded refs inclusion. createAppDefaults is not called anymore.
I have a project with lots of dependencies.
When I add
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
to main build.gradle, leakcanary-android is not in list of external libraries after gradle sync, although leakcanary-analyzer and leakcanary-watcher are there.
See screenshot:
We have the AndroidExcludedRefs which is nice. But please add an API to define our own excludes.
I am using ScheduledExecutorService, and start it in onResume and stop it on onPause, every time I leave the activity is shows a leak on the anonymous runnable, but since I canceled the task I think it detect the leak a bit fast before ScheduledExecutorService give away the task reference. Or am I missing something?
public void playAnimation() {
initAnimations();
final Handler handler = new Handler(Looper.getMainLooper());
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
mScheduledFuture = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
Timber.d("animate");
flipNextImage();
if (mPageIndicator != null) {
mPageIndicator.setOnPageChangeListener(null);
mPageIndicator.setCurrentItem(mSelectedImage);
switcherPager.setCurrentItem(mSelectedImage, true);
mPageIndicator.setOnPageChangeListener(onPageChangeListener);
} else {
switcherPager.setOnPageChangeListener(null);
switcherPager.setCurrentItem(mSelectedImage, true);
switcherPager.setOnPageChangeListener(onPageChangeListener);
}
}
});
}
}, 0, 3, TimeUnit.SECONDS);
}
public void stopAnimation() {
if (mScheduledFuture != null) {
mScheduledFuture.cancel(true);
mScheduledFuture = null;
}
}
I tried adding leak canary to our app and we get this crash:
java.lang.ExceptionInInitializerError
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:54)
at org.eclipse.mat.parser.internal.SnapshotFactory.parse(SnapshotFactory.java:193)
at org.eclipse.mat.parser.internal.SnapshotFactory.openSnapshot(SnapshotFactory.java:106)
at com.squareup.leakcanary.HeapAnalyzer.openSnapshot(HeapAnalyzer.java:134)
at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:87)
at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.NullPointerException: in == null
at java.util.Properties.load(Properties.java:246)
at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:28)
at org.eclipse.mat.util.MessageUtil.(MessageUtil.java:13)
... 10 more
I have 3 buildType
on my project, debug, staging and release. I suppose that debug and staging is loaded as debug types, not release, so when I generate a staging apk it will use debugCompile
option.
So I have:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
And I try go generate my signed apk for staging buildType
and it says:
Error:(12, 31) error: package com.squareup.leakcanary does not exist
Error:Execution failed for task ':app:compileStagingJava'.
> Compilation failed; see the compiler error output for details.
But if I use
compile 'com.squareup.leakcanary:leakcanary-android:1.3'
it generate my apk... what can I do?
I received this memory leak and not sure how to track down what is causing it. Any ideas?
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
* com.squareup.leakcanary.internal.DisplayLeakActivity has leaked:
* GC ROOT static com.android.internal.os.ZygoteInit.mResources
* references android.content.res.Resources.mContext
* references android.app.ContextImpl.mOuterContext
* leaks com.squareup.leakcanary.internal.DisplayLeakActivity instance
* Reference Key: bd8db00d-ce02-4f73-97fe-4bd36c65502f
* Device: samsung samsung GT-I9500 ja3gub
* Android Version: 4.4.2 API: 19
* Durations: watch=5015ms, gc=145ms, heap dump=543ms, analysis=13738ms
LeakCanary is awesome, I love the work you guys do.
I was going to introduce some leaks intentionally to test, but found this one instead. Seems to be a Motorola-ism as AOSP KitKat doesn't have an InputMethodManager.sInstance .
In com.teslacoilsw.launcher:#materinova.30:39030.
* com.teslacoilsw.launcher.preferences.fragments.DockPreferences has leaked:
* GC ROOT static android.view.inputmethod.InputMethodManager.sInstance
* references android.view.inputmethod.InputMethodManager.mCurRootView
* references com.android.internal.policy.impl.PhoneWindow$DecorView.mContext
* references com.teslacoilsw.launcher.preferences.SettingsActivity.mDelegate
* references android.support.v7.app.AppCompatDelegateImplV11.mActionBar
* references android.support.v7.internal.app.ToolbarActionBar.mDecorToolbar
* references android.support.v7.internal.widget.ToolbarWidgetWrapper.mToolbar
* references com.teslacoilsw.launcher.widget.FontFamilyToolbar.mMenuView
* references android.support.v7.widget.ActionMenuView.mPresenter
* references android.support.v7.widget.ActionMenuPresenter.mScrapActionButtonView
* references android.widget.FrameLayout.mChildren
* references array android.view.View[].[0]
* references com.teslacoilsw.launcher.widget.TintableSwitchCompat.mOnCheckedChangeListener
* references com.teslacoilsw.launcher.preferences.fragments.DockPreferences$1.this$0 (anonymous class implements android.widget.CompoundButton$OnCheckedChangeListener)
* leaks com.teslacoilsw.launcher.preferences.fragments.DockPreferences instance
* Reference Key: dee294f0-e103-4093-8556-5b0d59cfac16
* Device: motorola motorola XT1063 titan_retuglb
* Android Version: 4.4.4 API: 19
* Durations: watch=5007ms, gc=169ms, heap dump=719ms, analysis=18455ms
Motorola system version: 21.11.23.titan_retuglb.retuglb.en.US retus
Do I need to use build variant/flavor if I want to use this method?
When running a Espresso test using AndroidJunitTestRunner The tests start fine on sdks for android 5.5 but running the same test on Api < 19 fails in the call to install.
05-12 17:41:29.640 2017-2017/? E/MonitoringInstrumentation﹕ Dying now...
05-12 17:41:29.640 2017-2017/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: nz.org.winters.android.nzmobileaccountwidget, PID: 2017
java.lang.NoClassDefFoundError: com.squareup.leakcanary.ServiceHeapDumpListener
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:56)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
at nz.org.winters.android.nzmobileaccountwidget.CrashAppWrapper.onCreate(CrashAppWrapper.java:106)
Others?
In com.fastebro.androidrgbtool:1.5.0:10.
* com.fastebro.androidrgbtool.ui.MainActivity has leaked:
* GC ROOT android.media.MediaScannerConnection$1.this$0 (anonymous class extends android.media.IMediaScannerListener$Stub)
* references android.media.MediaScannerConnection.mContext
* leaks com.fastebro.androidrgbtool.ui.MainActivity instance
* Reference Key: b9ba263e-f5ce-4117-bfa5-23f921e13052
* Device: motorola google Nexus 6 shamu
* Android Version: 5.1 API: 22
* Durations: watch=5048ms, gc=153ms, heap dump=1707ms, analysis=15593ms
My code simply call the scanFile
like the ExternalStorage
official APIs demo.
Found it while testing my app but I'm not able to reproduce it systematically.
Hi!
leakcanary is very good! How to use leakcanary in eclipse?
Jaggedness. Meh.
Contributions welcome!
Hi,
When getting a reference to android.support.v7.app.ActionBar (i.e. actionBar = getSupportActionBar();), looks like the Object leaks :
- android.support.v7.internal.app.WindowDecorActionBar has leaked:
- GC ROOT static android.app.ActivityThread.sCurrentActivityThread
- references android.app.ActivityThread.mActivities
- references android.util.ArrayMap.mArray
- references array java.lang.Object[].[3]
- references android.app.ActivityThread$ActivityClientRecord.activity
- references com.dummy.demo.activity.HomeActivity.mDelegate
- references android.support.v7.app.ActionBarActivityDelegateHC.mActionBar
- leaks android.support.v7.internal.app.WindowDecorActionBar instance
- Reference Key: 2da7d526-6ff2-46a9-acc2-143896224525
- Device: asus google Nexus 7 razorg
- Android Version: 4.4.4 API: 19
It was possible to reproduce the same issue for the following devices :
* (...)Activity has leaked:
* GC ROOT android.content.ContentResolver$1.val$callback (anonymous class extends android.content.ISyncStatusObserver$Stub)
* references (...)Presenter.(...)Activity
* leaks (...)Activity instance
* Reference Key: a839032d-e812-4601-8703-4d068ff3e9fb
* Device: LGE google Nexus 5 hammerhead
* Android Version: 5.1 API: 22 LeakCanary: 1.3.1-SNAPSHOT
* Durations: watch=5019ms, gc=195ms, heap dump=1925ms, analysis=17520ms
All I do is:
public class Presenter {
public void onResume() {
final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
syncObserverHandle = ContentResolver.addStatusChangeListener(mask, this);
}
public void onPause() {
ContentResolver.removeStatusChangeListener(syncObserverHandle);
syncObserverHandle = null;
}
}
Presenter class has its Activity reference. Injection is done with Dagger 2, and component which keeps Presenter reference is set to null in onDestroy()
method.
A lot of APPs still support API Level 8. I think I would be better to support API Level 8 in leakcanary-android-no-op
.
I try to use eclipse replace gradle. It doesn't work. There are some problem block me.
05-11 17:36:01.631: D/AndroidHeapDumper(15195): Could not dump heap, previous analysis still is in progress.
05-11 17:45:33.151: W/dalvikvm(16376): Exception Ljava/lang/NullPointerException; thrown while initializing Lorg/eclipse/mat/util/MessageUtil;
With StrictMode
fully enabled:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyDeath()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyDeath()
.build());
I'm getting a crash on launch when calling LeakCanary.install(this);
StrictMode D StrictMode policy violation; ~duration=8 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=95 violation=2
D at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1137)
D at libcore.io.BlockGuardOs.access(BlockGuardOs.java:67)
D at java.io.File.doAccess(File.java:283)
D at java.io.File.exists(File.java:363)
D at android.app.ContextImpl.createFilesDirLocked(ContextImpl.java:997)
D at android.app.ContextImpl.getFilesDir(ContextImpl.java:1020)
D at android.content.ContextWrapper.getFilesDir(ContextWrapper.java:201)
D at com.squareup.leakcanary.AndroidHeapDumper.<init>(AndroidHeapDumper.java:29)
D at com.squareup.leakcanary.LeakCanary.androidWatcher(LeakCanary.java:68)
D at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:58)
D at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
D at com.robinhood.android.App.onCreate(App.java:56)
D at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
D at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518)
D at android.app.ActivityThread.access$1500(ActivityThread.java:144)
D at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
D at android.os.Handler.dispatchMessage(Handler.java:102)
D at android.os.Looper.loop(Looper.java:135)
D at android.app.ActivityThread.main(ActivityThread.java:5221)
D at java.lang.reflect.Method.invoke(Native Method)
D at java.lang.reflect.Method.invoke(Method.java:372)
D at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
D at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
AndroidRuntime D Shutting down VM
Calling LeakCanary.install()
on a background thread fixes the issue, just thought it may be worth addressing in the lib (or in the readme) since others may also have StrictMode
fully enabled for debug builds.
E/AndroidRuntime( 8237): FATAL EXCEPTION: IntentService[HeapAnalyzerService]
E/AndroidRuntime( 8237): Process: com.meizu.flyme.update:leakcanary, PID: 8237
E/AndroidRuntime( 8237): java.lang.NullPointerException: Attempt to get length of null array
E/AndroidRuntime( 8237): at com.squareup.leakcanary.HeapAnalyzer.cleanup(HeapAnalyzer.java:340)
E/AndroidRuntime( 8237): at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:109)
E/AndroidRuntime( 8237): at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
E/AndroidRuntime( 8237): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
E/AndroidRuntime( 8237): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 8237): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 8237): at android.os.HandlerThread.run(HandlerThread.java:61)
I've got a an activity with barcode scanner. When I exit with finish(), the memory usage stay the same.
So it is probably a memory leak with the context.
I keep seeing this come up in the log when trying to find a memory leak.
Is this normal?
* FAILURE:
org.eclipse.mat.SnapshotException: SnapshotFactoryImpl_Error_NoParserRegistered
at org.eclipse.mat.parser.internal.SnapshotFactory.parse(SnapshotFactory.java:220)
at org.eclipse.mat.parser.internal.SnapshotFactory.openSnapshot(SnapshotFactory.java:106)
at com.squareup.leakcanary.HeapAnalyzer.openSnapshot(HeapAnalyzer.java:134)
at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:87)
at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:61)
* Reference Key: dded0520-39d7-411c-99d1-6f8096f381ce
* Device: samsung samsung SAMSUNG-SM-N900A hlteuc
* Android Version: 4.3 API: 18
* Durations: watch=5026ms, gc=252ms, heap dump=1224ms, analysis=4627ms
* FAILURE:
java.lang.IllegalArgumentException: File does not exist: /data/data/com.myapp.testing/files/suspected_leak_heapdump.hprof
at com.squareup.leakcanary.HeapAnalyzer.checkForLeak(HeapAnalyzer.java:81)
at com.squareup.leakcanary.internal.HeapAnalyzerService.onHandleIntent(HeapAnalyzerService.java:56)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:61)
* Reference Key: 538bc49d-b79e-4357-a331-3b302b0008e0
* Device: samsung samsung SAMSUNG-SM-N900A hlteuc
* Android Version: 4.3 API: 18
* Durations: watch=5029ms, gc=221ms, heap dump=1196ms, analysis=0ms
I met an err "java.lang.StackOverflowError" in HeapAnalyzerService.
Creating and processing a Heap Dump does freeze UI for a significant amount of time for large heap dumps.
It's 8 seconds for me during which the application is unresponsive.
Of course the users won't be affected by that but our QA will.
Do you think it is a good idea to show a Toast (or any other notification) when you start the process. Will make users more aware why app is unresponsive.
@JakeWharton @loganj what are the steps?
After navigating a while through my app I got a StackOverFlowError...
AndroidRuntime E FATAL EXCEPTION: IntentService[HeapAnalyzerService]
E Process: com.weheartit:leakcanary, PID: 14442
E java.lang.StackOverflowError
E at java.io.BufferedOutputStream.write(BufferedOutputStream.java:135)
E at java.io.DataOutputStream.writeInt(DataOutputStream.java:180)
E at java.io.ObjectOutputStream.writeCyclicReference(ObjectOutputStream.java:812)
E at java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:427)
E at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:754)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1369)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.io.ObjectOutputStream.writeNewArray(ObjectOutputStream.java:1205)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1662)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
E at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.util.ArrayList.writeObject(ArrayList.java:648)
E at java.lang.reflect.Method.invokeNative(Native Method)
E at java.lang.reflect.Method.invoke(Method.java:515)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
E at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.util.ArrayList.writeObject(ArrayList.java:648)
E at java.lang.reflect.Method.invokeNative(Native Method)
E at java.lang.reflect.Method.invoke(Method.java:515)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
E at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
E at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
E at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
E at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
E at java.util.ArrayList.writeObject(ArrayList.java:648)
E at java.lang.reflect.Method.invokeNative(Native Method)
E at java.lang.reflect.Method.invoke(Method.java:515)
E at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
E at java.io.ObjectOutputStrea
When I use leakcanaryin my project, i get these errors:
Error:(19, 20) Failed to resolve: com.squareup.leakcanary:leakcanary-android-no-op:1.3
Error:(18, 18) Failed to resolve: com.squareup.leakcanary:leakcanary-android:1.3
How to solve these errors?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.