• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<lambda>null1 package shark
2 
3 import org.assertj.core.api.Assertions.assertThat
4 import org.junit.Test
5 import java.io.File
6 
7 /**
8  * Our path finding algorithm skips going through the content of strings to avoid unnecessary reads.
9  * We add back the corresponding size when computing the shallow size of retained strings,
10  * however that only works if those byte arrays aren't reachable through other references.
11  * If they were, this could either inflate the retained size number (byte array should not be
12  * considered retained) or deflate it (byte array counted twice when reached from two retained
13  * instances).
14  */
15 class StringPathFinderOptimTest {
16 
17   @Test fun `String#value not reachable on Android O`() {
18     val hprofFile = "leak_asynctask_o.hprof".classpathFile()
19     val analysis = findStringContent(hprofFile)
20     assertThat(analysis.allLeaks.count()).isEqualTo(0)
21   }
22 
23   @Test fun `String#value not reachable on Android M`() {
24     val hprofFile = "leak_asynctask_m.hprof".classpathFile()
25     val analysis = findStringContent(hprofFile)
26     assertThat(analysis.allLeaks.count()).isEqualTo(0)
27   }
28 
29   @Test fun `String#value only reachable for String#ASCII pre Android M`() {
30     val hprofFile = "leak_asynctask_pre_m.hprof".classpathFile()
31     val analysis = findStringContent(hprofFile)
32     assertThat(analysis.allLeaks.count()).isEqualTo(1)
33     val path = analysis.applicationLeaks.first().leakTraces.first()
34     assertThat(path.referencePath.first().referenceName).isEqualTo("ASCII")
35   }
36 
37   private fun findStringContent(hprofFile: File): HeapAnalysisSuccess {
38     val heapAnalyzer = HeapAnalyzer(OnAnalysisProgressListener.NO_OP)
39     val analysis = heapAnalyzer.analyze(
40       heapDumpFile = hprofFile,
41       leakingObjectFinder = { graph ->
42         graph.findClassByName("java.lang.String")!!.instances.map { instance ->
43           instance["java.lang.String", "value"]?.value?.asNonNullObjectId!!
44         }.toSet()
45       },
46       referenceMatchers = AndroidReferenceMatchers.appDefaults,
47       computeRetainedHeapSize = true,
48       objectInspectors = AndroidObjectInspectors.appDefaults,
49       metadataExtractor = AndroidMetadataExtractor
50     )
51     println(analysis)
52     return analysis as HeapAnalysisSuccess
53   }
54 }
55