mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 05:15:22 +00:00
8026789: Update test/java/lang/instrument/Re(transform|define)BigClass.sh test to use NMT for memory leak detection
Reviewed-by: dcubed
This commit is contained in:
parent
28fc7fbaeb
commit
7108f683fc
@ -134,10 +134,6 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
|
||||
# 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
|
||||
|
||||
|
||||
70
jdk/test/java/lang/instrument/NMTHelper.java
Normal file
70
jdk/test/java/lang/instrument/NMTHelper.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
@ -58,11 +58,19 @@ fi
|
||||
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
|
||||
|
||||
@ -26,16 +26,23 @@ import java.io.*;
|
||||
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 @@ public class RedefineBigClassApp {
|
||||
}
|
||||
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)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,8 +58,16 @@ fi
|
||||
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
|
||||
|
||||
@ -26,16 +26,23 @@ import java.io.*;
|
||||
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 @@ public class RetransformBigClassApp {
|
||||
}
|
||||
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)");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user