8026789: Update test/java/lang/instrument/Re(transform|define)BigClass.sh test to use NMT for memory leak detection
Reviewed-by: dcubed
--- a/jdk/test/ProblemList.txt Wed Oct 23 14:38:22 2013 +0100
+++ b/jdk/test/ProblemList.txt Wed Oct 23 15:55:31 2013 +0200
@@ -134,10 +134,6 @@
# 8021230
java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all
-# 8023201
-java/lang/instrument/RetransformBigClass.sh generic-all
-java/lang/instrument/RedefineBigClass.sh generic-all
-
# 8026502
java/lang/invoke/MethodHandleConstants.java generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/NMTHelper.java Wed Oct 23 15:55:31 2013 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.DiagnosticCommandMBean;
+
+public class NMTHelper
+{
+ public static void baseline() {
+ executeDcmd("vmNativeMemory", "baseline");
+ }
+
+ // Total: reserved=3484685KB +293KB, committed=266629KB +293KB
+ private static Pattern totalLine = Pattern.compile("^Total: reserved=\\d+KB .*KB, committed=\\d+KB (.*)KB$");
+
+ public static long committedDiff() throws Exception {
+ String res = (String) executeDcmd("vmNativeMemory", "detail.diff");
+ String[] lines = res.split("\n");
+ for (String line : lines) {
+ Matcher matcher = totalLine.matcher(line);
+ if (matcher.matches()) {
+ String committed = matcher.group(1);
+ return Long.parseLong(committed);
+ }
+ }
+ throw new Exception("Could not find the Total line in the NMT output.");
+ }
+
+ private static String executeDcmd(String cmd, String ... args) {
+ DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
+ Object[] dcmdArgs = {args};
+ String[] signature = {String[].class.getName()};
+
+ try {
+ System.out.print("> " + cmd + " ");
+ for (String s : args) {
+ System.out.print(s + " ");
+ }
+ System.out.println(":");
+ String result = (String) dcmd.invoke(cmd, dcmdArgs, signature);
+ System.out.println(result);
+ return result;
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+}
--- a/jdk/test/java/lang/instrument/RedefineBigClass.sh Wed Oct 23 14:38:22 2013 +0100
+++ b/jdk/test/java/lang/instrument/RedefineBigClass.sh Wed Oct 23 15:55:31 2013 +0200
@@ -58,11 +58,19 @@
JAVAC="${COMPILEJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
+# Does this VM support the 'detail' level of NMT?
+"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version
+if [ "$?" = 0 ]; then
+ NMT=-XX:NativeMemoryTracking=detail
+else
+ NMT=-XX:NativeMemoryTracking=summary
+fi
+
"${JAVA}" ${TESTVMOPTS} \
- -XX:TraceRedefineClasses=3 \
+ -XX:TraceRedefineClasses=3 ${NMT} \
-javaagent:RedefineBigClassAgent.jar=BigClass.class \
-classpath "${TESTCLASSES}" RedefineBigClassApp \
- > output.log 2>&1
+ > output.log 2>&1
result=$?
cat output.log
--- a/jdk/test/java/lang/instrument/RedefineBigClassApp.java Wed Oct 23 14:38:22 2013 +0100
+++ b/jdk/test/java/lang/instrument/RedefineBigClassApp.java Wed Oct 23 15:55:31 2013 +0200
@@ -26,16 +26,23 @@
public class RedefineBigClassApp {
/**
* Memory leak is assumed, if application consumes more than specified amount of memory during its execution.
- * The number is given in Kb.
+ * The number is given in KB.
*/
- private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb
+ private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32MB
public static void main(String[] args) throws Exception {
System.out.println("Creating instance of " +
RedefineBigClassAgent.clz);
RedefineBigClassAgent.clz.newInstance();
- long vMemBefore = getVMemSize();
+ // Do a short warmup before creating the NMT baseline
+ try {
+ Thread.sleep(5 * 1000);
+ } catch (InterruptedException ie) {
+ }
+
+ NMTHelper.baseline();
+
int count = 0;
while (!RedefineBigClassAgent.doneRedefining) {
System.out.println("App loop count: " + ++count);
@@ -46,39 +53,12 @@
}
System.out.println("App looped " + count + " times.");
- long vMemAfter = getVMemSize();
- if (vMemBefore == 0 || vMemAfter == 0) {
- System.err.println("WARNING: Cannot perform memory leak detection on this OS");
- } else {
- long vMemDelta = vMemAfter - vMemBefore;
- if (vMemDelta > MEM_LEAK_THRESHOLD) {
- System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " +
- "(greater than " + MEM_LEAK_THRESHOLD + "Kb)");
- System.exit(1);
- }
- System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " +
- "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)");
+ long committedDiff = NMTHelper.committedDiff();
+ if (committedDiff > MEM_LEAK_THRESHOLD) {
+ throw new Exception("FAIL: Committed memory usage increased by " + committedDiff + "KB " +
+ "(greater than " + MEM_LEAK_THRESHOLD + "KB)");
}
- System.exit(0);
- }
-
- /**
- * Return size of virtual memory allocated to the process in Kb.
- * Linux specific. On other platforms and in case of any errors return 0.
- */
- private static long getVMemSize() {
-
- // Refer to the Linux proc(5) man page for details about /proc/self/stat file
- //
- // In short, this file contains status information about the current process
- // written in one line. The fields are separated with spaces.
- // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes'
-
- try (FileReader fileReader = new FileReader("/proc/self/stat");
- BufferedReader bufferedReader = new BufferedReader(fileReader)) {
- String line = bufferedReader.readLine();
- return Long.parseLong(line.split(" ")[22]) / 1024;
- } catch (Exception ex) {}
- return 0;
+ System.err.println("PASS: Committed memory usage increased by " + committedDiff + "KB " +
+ "(not greater than " + MEM_LEAK_THRESHOLD + "KB)");
}
}
--- a/jdk/test/java/lang/instrument/RetransformBigClass.sh Wed Oct 23 14:38:22 2013 +0100
+++ b/jdk/test/java/lang/instrument/RetransformBigClass.sh Wed Oct 23 15:55:31 2013 +0200
@@ -58,8 +58,16 @@
JAVAC="${COMPILEJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
+# Does this VM support the 'detail' level of NMT?
+"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version
+if [ "$?" = 0 ]; then
+ NMT=-XX:NativeMemoryTracking=detail
+else
+ NMT=-XX:NativeMemoryTracking=summary
+fi
+
"${JAVA}" ${TESTVMOPTS} \
- -XX:TraceRedefineClasses=3 \
+ -XX:TraceRedefineClasses=3 ${NMT} \
-javaagent:RetransformBigClassAgent.jar=BigClass.class \
-classpath "${TESTCLASSES}" RetransformBigClassApp \
> output.log 2>&1
--- a/jdk/test/java/lang/instrument/RetransformBigClassApp.java Wed Oct 23 14:38:22 2013 +0100
+++ b/jdk/test/java/lang/instrument/RetransformBigClassApp.java Wed Oct 23 15:55:31 2013 +0200
@@ -26,16 +26,23 @@
public class RetransformBigClassApp {
/**
* Memory leak is assumed, if application consumes more than specified amount of memory during its execution.
- * The number is given in Kb.
+ * The number is given in KB.
*/
- private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb
+ private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32MB
public static void main(String[] args) throws Exception {
System.out.println("Creating instance of " +
RetransformBigClassAgent.clz);
RetransformBigClassAgent.clz.newInstance();
- long vMemBefore = getVMemSize();
+ // Do a short warmup before creating the NMT baseline
+ try {
+ Thread.sleep(5 * 1000);
+ } catch (InterruptedException ie) {
+ }
+
+ NMTHelper.baseline();
+
int count = 0;
while (!RetransformBigClassAgent.doneRetransforming) {
System.out.println("App loop count: " + ++count);
@@ -46,39 +53,12 @@
}
System.out.println("App looped " + count + " times.");
- long vMemAfter = getVMemSize();
- if (vMemBefore == 0 || vMemAfter == 0) {
- System.err.println("WARNING: Cannot perform memory leak detection on this OS");
- } else {
- long vMemDelta = vMemAfter - vMemBefore;
- if (vMemDelta > MEM_LEAK_THRESHOLD) {
- System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " +
- "(greater than " + MEM_LEAK_THRESHOLD + "Kb)");
- System.exit(1);
- }
- System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " +
- "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)");
+ long committedDiff = NMTHelper.committedDiff();
+ if (committedDiff > MEM_LEAK_THRESHOLD) {
+ throw new Exception("FAIL: Committed memory usage increased by " + committedDiff + "KB " +
+ "(greater than " + MEM_LEAK_THRESHOLD + "KB)");
}
- System.exit(0);
- }
-
- /**
- * Return size of virtual memory allocated to the process in Kb.
- * Linux specific. On other platforms and in case of any errors return 0.
- */
- private static long getVMemSize() {
-
- // Refer to the Linux proc(5) man page for details about /proc/self/stat file
- //
- // In short, this file contains status information about the current process
- // written in one line. The fields are separated with spaces.
- // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes'
-
- try (FileReader fileReader = new FileReader("/proc/self/stat");
- BufferedReader bufferedReader = new BufferedReader(fileReader)) {
- String line = bufferedReader.readLine();
- return Long.parseLong(line.split(" ")[22]) / 1024;
- } catch (Exception ex) {}
- return 0;
+ System.err.println("PASS: Committed memory usage increased by " + committedDiff + "KB " +
+ "(not greater than " + MEM_LEAK_THRESHOLD + "KB)");
}
}