OpenJDK / jdk / jdk
changeset 21347:21c6a82adf04
8026789: Update test/java/lang/instrument/Re(transform|define)BigClass.sh test to use NMT for memory leak detection
Reviewed-by: dcubed
author | sla |
---|---|
date | Wed, 23 Oct 2013 15:55:31 +0200 |
parents | 793a4fec2332 |
children | e30c5696b4c5 |
files | jdk/test/ProblemList.txt jdk/test/java/lang/instrument/NMTHelper.java jdk/test/java/lang/instrument/RedefineBigClass.sh jdk/test/java/lang/instrument/RedefineBigClassApp.java jdk/test/java/lang/instrument/RetransformBigClass.sh jdk/test/java/lang/instrument/RetransformBigClassApp.java |
diffstat | 6 files changed, 121 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- 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)"); } }