Add a heap dump utility
Change-Id: Ic86c3a252b654be384ca74325c33fe99407fa96a
diff --git a/src/main/java/com/android/tools/r8/utils/HeapUtils.java b/src/main/java/com/android/tools/r8/utils/HeapUtils.java
new file mode 100644
index 0000000..6834f66
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/HeapUtils.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Path;
+import javax.management.MBeanServer;
+
+public class HeapUtils {
+
+ private static final String HOTSPOT_MBEAN_NAME = "com.sun.management:type=HotSpotDiagnostic";
+ private static volatile HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean;
+
+ private static void initHotSpotMBean() throws IOException {
+ if (hotSpotDiagnosticMXBean == null) {
+ synchronized (HeapUtils.class) {
+ if (hotSpotDiagnosticMXBean == null) {
+ hotSpotDiagnosticMXBean = getHotSpotDiagnosticMXBean();
+ }
+ }
+ }
+ }
+
+ private static HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean() throws IOException {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ return ManagementFactory.newPlatformMXBeanProxy(
+ server, HOTSPOT_MBEAN_NAME, HotSpotDiagnosticMXBean.class);
+ }
+
+ public static void dumpHeap(Path fileName, boolean live) throws IOException {
+ initHotSpotMBean();
+ hotSpotDiagnosticMXBean.dumpHeap(fileName.toString(), live);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/heap/HeapDumpTest.java b/src/test/java/com/android/tools/r8/heap/HeapDumpTest.java
new file mode 100644
index 0000000..19a3c15
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/heap/HeapDumpTest.java
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.heap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.HeapUtils;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Test;
+
+public class HeapDumpTest extends TestBase {
+
+ @Test
+ public void testHeapDump() throws Exception {
+ Path heapDumpDir = temp.newFolder().toPath();
+ Path heapDump = heapDumpDir.resolve("test.hprof");
+ HeapUtils.dumpHeap(heapDump, true);
+ assertTrue(heapDump.toFile().exists());
+ String header = "JAVA PROFILE 1.0.2";
+ assertTrue(heapDump.toFile().length() > header.length());
+ try (InputStream is = Files.newInputStream(heapDump)) {
+ byte[] buffer = new byte[header.length()];
+ int bytes = is.read(buffer);
+ assertEquals(buffer.length, bytes);
+ assertEquals(header, new String(buffer));
+ }
+ }
+}