leakcanary icon indicating copy to clipboard operation
leakcanary copied to clipboard

Test ordering issue when using @SkipLeakDetection without Orchestrator

Open alexvanyo opened this issue 2 years ago • 1 comments

Description

Using @SkipLeakDetection to disable leak detection for some tests seems to cause non-determinism based on ordering for leak-checking tests running after the tests with leak detection disabled.

Steps to Reproduce

My natural test ordering results in the following:

  • Group A of tests run first, which have @SkipLeakDetection due to existing leaks
  • Group B of tests, with leak detection enabled, run after, and analyzing causes out of memory errors

https://github.com/alexvanyo/composelife/pull/360

That PR reveals the issue by removing my workaround (using Orchestrator to keep the state between tests more independent bypasses the ordering issue).

Logcat
2022-05-22 18:16:21.695 26790-26804 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Background concurrent copying GC freed 1160400(29MB) AllocSpace objects, 22(440KB) LOS objects, 13% free, 151MB/175MB, paused 408us total 323.765ms
2022-05-22 18:16:23.571 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:23.571 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:23.585 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc young concurrent copying GC freed 330272(7762KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 183MB/183MB, paused 1.782ms total 13.090ms
2022-05-22 18:16:23.585 26790-26804 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  WaitForGcToComplete blocked Background on HeapTrim for 13.699ms
2022-05-22 18:16:23.585 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:23.757 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Clamp target GC heap from 204MB to 192MB
2022-05-22 18:16:23.757 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc concurrent copying GC freed 96608(2551KB) AllocSpace objects, 2(40KB) LOS objects, 5% free, 180MB/192MB, paused 362us total 171.501ms
2022-05-22 18:16:23.757 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Forcing collection of SoftReferences for 32MB allocation
2022-05-22 18:16:23.757 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:24.196 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Clamp target GC heap from 203MB to 192MB
2022-05-22 18:16:24.196 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc concurrent copying GC freed 50989(1228KB) AllocSpace objects, 2(44KB) LOS objects, 6% free, 179MB/192MB, paused 959us total 438.752ms
2022-05-22 18:16:24.197 26790-26804 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  WaitForGcToComplete blocked Background on HeapTrim for 610.987ms
2022-05-22 18:16:24.197 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    W  Throwing OutOfMemoryError "Failed to allocate a 33554456 byte allocation with 13020808 free bytes and 12MB until OOM, target footprint 201326592, growth limit 201326592" (VmSize 1488580 kB)
2022-05-22 18:16:24.197 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:24.198 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:24.205 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc young concurrent copying GC freed 4(79KB) AllocSpace objects, 0(0B) LOS objects, 6% free, 179MB/192MB, paused 1.413ms total 7.445ms
2022-05-22 18:16:24.206 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:24.372 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Clamp target GC heap from 203MB to 192MB
2022-05-22 18:16:24.373 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc concurrent copying GC freed 4(16KB) AllocSpace objects, 0(0B) LOS objects, 6% free, 179MB/192MB, paused 361us total 166.407ms
2022-05-22 18:16:24.373 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Forcing collection of SoftReferences for 32MB allocation
2022-05-22 18:16:24.373 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Starting a blocking GC Alloc
2022-05-22 18:16:24.648 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Clamp target GC heap from 203MB to 192MB
2022-05-22 18:16:24.649 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    I  Alloc concurrent copying GC freed 10(16KB) AllocSpace objects, 0(0B) LOS objects, 6% free, 179MB/192MB, paused 1.351ms total 275.580ms
2022-05-22 18:16:24.649 26790-26815 oselife.ui.tes          com.alexvanyo.composelife.ui.test    W  Throwing OutOfMemoryError "Failed to allocate a 33554456 byte allocation with 13070024 free bytes and 12MB until OOM, target footprint 201326592, growth limit 201326592" (VmSize 1488580 kB)
2022-05-22 18:16:24.657 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  Heap Analysis failed, retrying in 10s in case the heap dump was not fully baked yet. Copy of original heap dump available at /data/user/0/com.alexvanyo.composelife.ui.test/files/copy-instrumentation_tests_2022-05-22_18-14-33_175.hprof
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  java.lang.RuntimeException: Not enough memory to allocate buffers for rehashing: 2097152 -> 4194304
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateBuffers(LongLongScatterMap.kt:326)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateThenInsertThenRehash(LongLongScatterMap.kt:358)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.set(LongLongScatterMap.kt:103)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.DominatorTree.updateDominated(DominatorTree.kt:51)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder$VisitTracker$Dominated.visited(PathFinder.kt:63)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.enqueue(PathFinder.kt:224)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.findPathsFromGcRoots(PathFinder.kt:170)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.findPathsFromGcRoots(PathFinder.kt:135)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.findLeaks(HeapAnalyzer.kt:275)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyzeGraph(HeapAnalyzer.kt:253)
2022-05-22 18:16:24.658 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyze$shark(HeapAnalyzer.kt:217)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyze(HeapAnalyzer.kt:166)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.internal.InstrumentationHeapAnalyzer.analyze(InstrumentationHeapAnalyzer.kt:63)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.internal.RetryingHeapAnalyzer.analyze(RetryingHeapAnalyzer.kt:26)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.AndroidDetectLeaksAssert.runLeakChecks(AndroidDetectLeaksAssert.kt:80)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.AndroidDetectLeaksAssert.assertNoLeaks(AndroidDetectLeaksAssert.kt:34)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.LeakAssertions.assertNoLeaks(LeakAssertions.kt:21)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.DetectLeaksAfterTestSuccess$apply$1.evaluate(DetectLeaksAfterTestSuccess.kt:26)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.TestDescriptionHolder$wrap$1.evaluate(TestDescriptionHolder.kt:43)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
2022-05-22 18:16:24.659 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:162)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.Suite.runChild(Suite.java:128)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.Suite.runChild(Suite.java:27)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.660 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:67)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:438)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  Caused by: java.lang.OutOfMemoryError: Failed to allocate a 33554456 byte allocation with 13070024 free bytes and 12MB until OOM, target footprint 201326592, growth limit 201326592
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateBuffers(LongLongScatterMap.kt:322)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	... 46 more
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyze$shark(HeapAnalyzer.kt:225)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyze(HeapAnalyzer.kt:166)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.internal.InstrumentationHeapAnalyzer.analyze(InstrumentationHeapAnalyzer.kt:63)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.internal.RetryingHeapAnalyzer.analyze(RetryingHeapAnalyzer.kt:26)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.AndroidDetectLeaksAssert.runLeakChecks(AndroidDetectLeaksAssert.kt:80)
2022-05-22 18:16:24.661 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.AndroidDetectLeaksAssert.assertNoLeaks(AndroidDetectLeaksAssert.kt:34)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.LeakAssertions.assertNoLeaks(LeakAssertions.kt:21)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.DetectLeaksAfterTestSuccess$apply$1.evaluate(DetectLeaksAfterTestSuccess.kt:26)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at leakcanary.TestDescriptionHolder$wrap$1.evaluate(TestDescriptionHolder.kt:43)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:162)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.Suite.runChild(Suite.java:128)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.Suite.runChild(Suite.java:27)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
2022-05-22 18:16:24.662 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:67)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:438)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  Caused by: java.lang.RuntimeException: Not enough memory to allocate buffers for rehashing: 2097152 -> 4194304
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateBuffers(LongLongScatterMap.kt:326)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateThenInsertThenRehash(LongLongScatterMap.kt:358)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.set(LongLongScatterMap.kt:103)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.DominatorTree.updateDominated(DominatorTree.kt:51)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder$VisitTracker$Dominated.visited(PathFinder.kt:63)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.enqueue(PathFinder.kt:224)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.findPathsFromGcRoots(PathFinder.kt:170)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.PathFinder.findPathsFromGcRoots(PathFinder.kt:135)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.findLeaks(HeapAnalyzer.kt:275)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyzeGraph(HeapAnalyzer.kt:253)
2022-05-22 18:16:24.663 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.HeapAnalyzer.analyze$shark(HeapAnalyzer.kt:217)
2022-05-22 18:16:24.664 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	... 36 more
2022-05-22 18:16:24.664 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  Caused by: java.lang.OutOfMemoryError: Failed to allocate a 33554456 byte allocation with 13070024 free bytes and 12MB until OOM, target footprint 201326592, growth limit 201326592
2022-05-22 18:16:24.664 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	at shark.internal.hppc.LongLongScatterMap.allocateBuffers(LongLongScatterMap.kt:322)
2022-05-22 18:16:24.664 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  	... 46 more
2022-05-22 18:16:24.664 26790-26815 LeakCanary              com.alexvanyo.composelife.ui.test    D  

Expected behavior:

Leak checks for tests running after the tests annotated with @SkipLeakDetection pass, just as they do when those tests are run individually. If I run just Group B, then the tests pass without any leaks detected.

Version Information

  • LeakCanary version: 2.9.1
  • Android OS version: API 30
  • Gradle version: 7.5-rc-1

Additional Information

I'm not sure if this is entirely actionable, since having leaks in the first place is the real issue 🙃 . But figured I'd report an issue since debugging non-deterministic tests isn't very fun. There's also a pretty simple workaround by using Orchestrator to avoid sharing state between tests.

Based on https://github.com/square/leakcanary/blob/7edf572f4000391e28ef74c5f1ed62aa61ffd945/leakcanary-android-instrumentation/src/main/java/leakcanary/AndroidDetectLeaksAssert.kt#L30

It looks like when leak detection is skipped, it bypasses all of the analysis, so my guess is that leaves state around for later tests to potentially fail on. Maybe there's an opportunity to clear out that state in some way if a test is known to expose a leak?

alexvanyo avatar May 22 '22 17:05 alexvanyo

Thanks for the report!

Actually what's going on here is that leak detection has a side effect (which you can see in that source link you shared): calling retainedObjectsChecker.clearObjectsWatchedBeforeHeapDump() which lets go of weak references to objects watched until then.

We should clear watched objects in the skip case as well, as we don't want leaks from known bad tests to make the next test fail.

pyricau avatar May 26 '22 00:05 pyricau

This should have been fixed by https://github.com/square/leakcanary/pull/2363 which shipped in 2.9

pyricau avatar Nov 11 '22 05:11 pyricau