forked from square/leakcanary
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lower memory usage when parsing heap dumps on M
Parsing an hprof file generated on M results in a Snapshot filled with duplicate GC root entries. This extra memory usage leaves little room for LeakCanary to analyze and find the leak trace and often results in an OutOfMemoryError. This commit removes the duplicate GC root entries to alleviate the memory pressure. Fixes square#223
- Loading branch information
Showing
3 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/test/java/com/squareup/leakcanary/HeapAnalyzerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.squareup.leakcanary; | ||
|
||
import com.squareup.haha.perflib.RootObj; | ||
import com.squareup.haha.perflib.Snapshot; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
import static com.squareup.haha.perflib.RootType.NATIVE_STATIC; | ||
import static com.squareup.haha.perflib.RootType.SYSTEM_CLASS; | ||
import static java.util.Arrays.asList; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
public class HeapAnalyzerTest { | ||
private static final ExcludedRefs NO_EXCLUDED_REFS = null; | ||
private static final List<RootObj> DUP_ROOTS = | ||
asList(new RootObj(SYSTEM_CLASS, 6L), | ||
new RootObj(SYSTEM_CLASS, 5L), | ||
new RootObj(SYSTEM_CLASS, 3L), | ||
new RootObj(SYSTEM_CLASS, 5L), | ||
new RootObj(NATIVE_STATIC, 3L)); | ||
|
||
private HeapAnalyzer heapAnalyzer; | ||
|
||
@Before | ||
public void setUp() { | ||
heapAnalyzer = new HeapAnalyzer(NO_EXCLUDED_REFS); | ||
} | ||
|
||
@Test | ||
public void ensureUniqueRoots() { | ||
Snapshot snapshot = createSnapshot(DUP_ROOTS); | ||
|
||
heapAnalyzer.deduplicateGcRoots(snapshot); | ||
|
||
Collection<RootObj> uniqueRoots = snapshot.getGCRoots(); | ||
assertThat(uniqueRoots).hasSize(4); | ||
|
||
List<Long> rootIds = new ArrayList<>(); | ||
for (RootObj root : uniqueRoots) { | ||
rootIds.add(root.getId()); | ||
} | ||
Collections.sort(rootIds); | ||
|
||
// 3 appears twice because even though two RootObjs have the same id, they're different types. | ||
assertThat(rootIds).containsExactly(3L, 3L, 5L, 6L); | ||
} | ||
|
||
private Snapshot createSnapshot(List<RootObj> gcRoots) { | ||
Snapshot snapshot = new Snapshot(null); | ||
for (RootObj root : gcRoots) { | ||
snapshot.addRoot(root); | ||
} | ||
return snapshot; | ||
} | ||
} |