提交 ea734953 编写于 作者: I igerasim

6977426: sun/tools tests can intermittently fail to find app's Java pid

Reviewed-by: dfuchs, jbachorik, egahlin, sjiang
上级 819f1e68
......@@ -333,8 +333,7 @@ needs_jdk = \
java/util/Collections/EmptyIterator.java \
java/util/concurrent/locks/Lock/TimedAcquireLeak.java \
java/util/jar/JarInputStream/ExtraFileInMetaInf.java \
java/util/logging/AnonLoggerWeakRefLeak.sh \
java/util/logging/LoggerWeakRefLeak.sh \
java/util/logging/TestLoggerWeakRefLeak.java \
java/util/zip/3GBZipFiles.sh \
jdk/lambda/FDTest.java \
jdk/lambda/separate/Compiler.java \
......
/*
* Copyright (c) 2010, 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.logging.*;
public class AnonLoggerWeakRefLeak extends SimpleApplication {
// The test driver script will allow this program to run until we
// reach DEFAULT_LOOP_TIME or a decrease in instance counts is
// observed. For this particular WeakReference leak, the count
// was always observed to be increasing so if we get a decreasing
// count, then the leak is fixed in the bits being tested.
// Two minutes has been enough time to observe a decrease in
// fixed bits on overloaded systems, but the test will likely
// finish more quickly.
public static int DEFAULT_LOOP_TIME = 120; // time is in seconds
// execute the AnonLoggerWeakRefLeak app work
public void doMyAppWork(String[] args) throws Exception {
int loop_time = 0;
int max_loop_time = DEFAULT_LOOP_TIME;
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default time of "
+ max_loop_time + " seconds.");
} else {
try {
max_loop_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
throw new RuntimeException("Error: '" + args[1]
+ "': is not a valid seconds value.");
}
}
long count = 0;
long now = 0;
long startTime = System.currentTimeMillis();
while (now < (startTime + (max_loop_time * 1000))) {
if ((count % 1000) == 0) {
// Print initial call count to let caller know that
// we're up and running and then periodically
System.out.println("INFO: call count = " + count);
}
for (int i = 0; i < 100; i++) {
// this Logger call is leaking a WeakReference in Logger.kids
java.util.logging.Logger.getAnonymousLogger();
count++;
}
try {
// delay for 1/10 of a second to avoid CPU saturation
Thread.sleep(100);
} catch (InterruptedException ie) {
// ignore any exceptions
}
now = System.currentTimeMillis();
}
System.out.println("INFO: final loop count = " + count);
}
public static void main(String[] args) throws Exception {
AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}
#!/bin/sh
#
# Copyright (c) 2010, 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.
#
# @test
# @bug 6942989
# @summary Check for WeakReference leak in anonymous Logger objects
# @author Daniel D. Daugherty
#
# @library ../../../sun/tools/common
# @build SimpleApplication ShutdownSimpleApplication
# @build AnonLoggerWeakRefLeak
# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
#
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
TEST_NAME="AnonLoggerWeakRefLeak"
TARGET_CLASS="java\.lang\.ref\.WeakReference"
# MAIN begins here
#
seconds=
if [ "$#" -gt 0 ]; then
seconds="$1"
fi
# see if this version of jmap supports the '-histo:live' option
jmap_option="-histo:live"
set +e
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
# usage message doesn't show ':live' option
if $isWindows; then
# If SA isn't present, then jmap gives a different usage message
# that doesn't show the ':live' option. However, that's a bug that
# is covered by 6971851 so we try using the option just to be sure.
# For some reason, this problem has only been seen on OpenJDK6 on
# Windows. Not sure why.
set +e
# Note: Don't copy this code to try probing process 0 on Linux; it
# will kill the process group in strange ways.
"${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
# Usage message generated so flag the problem.
status=1
else
# No usage message so clear the flag.
status=0
fi
fi
if [ "$status" != 0 ]; then
echo "WARNING: 'jmap $jmap_option' is not supported on this platform"
echo "WARNING: so this test cannot work reliably. Aborting!"
exit 0
fi
fi
# Start application and use TEST_NAME.port for coordination
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
finished_early=false
decreasing_cnt=0
increasing_cnt=0
loop_cnt=0
prev_instance_cnt=0
MAX_JMAP_TRY_CNT=10
jmap_retry_cnt=0
loop_cnt_on_retry=0
while true; do
# see if the target process has finished its run and bail if it has
set +e
grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
break
fi
# Output format for 'jmap -histo' in JDK1.5.0:
#
# <#bytes> <#instances> <class_name>
#
# Output format for 'jmap -histo:live':
#
# <num>: <#instances> <#bytes> <class_name>
#
set +e
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
echo "INFO: jmap exited with exit code = $status"
# There are intermittent jmap failures; see 6498448.
#
# So far the following have been observed in a jmap call
# that was not in a race with target process termination:
#
# (Solaris specific, 2nd sample)
# <pid>: Unable to open door: target process not responding or HotSpot VM not loaded
# The -F option can be used when the target process is not responding
#
# (on Solaris so far)
# java.io.IOException
#
# (on Solaris so far, 1st sample)
# <pid>: Permission denied
#
sed 's/^/INFO: /' "$TEST_NAME.jmap"
if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then
# loop count hasn't changed
jmap_retry_cnt=`expr $jmap_retry_cnt + 1`
else
# loop count has changed so remember it
jmap_retry_cnt=1
loop_cnt_on_retry="$loop_cnt"
fi
# This is '-ge' because we have the original attempt plus
# MAX_JMAP_TRY_CNT - 1 retries.
if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then
echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \
"without making any progress."
echo "FAIL: jmap is unable to take any samples." >&2
killApplication
exit 2
fi
# short delay and try again
# Note: sleep 1 didn't help with "<pid>: Permission denied"
sleep 2
echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)."
continue
fi
set +e
instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \
"$TEST_NAME.jmap" \
| sed '
# strip leading whitespace; does nothing in JDK1.5.0
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <#bytes> in JDK1.5.0; does nothing otherwise
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <num>: field; does nothing in JDK1.5.0
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <class_name> field
s/'"${PATTERN_WS}"'.*//
'`
set -e
if [ -z "$instance_cnt" ]; then
echo "INFO: instance count is unexpectedly empty"
if [ "$loop_cnt" = 0 ]; then
echo "INFO: on the first iteration so no sample was found."
echo "INFO: There is likely a problem with the sed filter."
echo "INFO: start of jmap output:"
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
echo "FAIL: cannot find the instance count value." >&2
killApplication
exit 2
fi
else
echo "INFO: instance_cnt = $instance_cnt"
if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then
increasing_cnt=`expr $increasing_cnt + 1`
else
# actually decreasing or the same
decreasing_cnt=`expr $decreasing_cnt + 1`
# For this particular WeakReference leak, the count was
# always observed to be increasing so if we get a decreasing
# or the same count, then the leak is fixed in the bits
# being tested.
echo "INFO: finishing early due to non-increasing instance count."
finished_early=true
killApplication
break
fi
prev_instance_cnt="$instance_cnt"
fi
# delay between samples
sleep 5
loop_cnt=`expr $loop_cnt + 1`
done
if [ $finished_early = false ]; then
stopApplication "$TEST_NAME.port"
waitForApplication
fi
echo "INFO: $TEST_NAME has finished running."
echo "INFO: increasing_cnt = $increasing_cnt"
echo "INFO: decreasing_cnt = $decreasing_cnt"
if [ "$jmap_retry_cnt" -gt 0 ]; then
echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)"
fi
if [ "$loop_cnt" = 0 ]; then
echo "FAIL: jmap is unable to take any samples." >&2
exit 2
fi
echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects"
if [ "$decreasing_cnt" = 0 ]; then
echo "INFO: is always increasing."
echo "FAIL: This indicates that there is a memory leak." >&2
exit 2
fi
echo "INFO: is not always increasing."
echo "PASS: This indicates that there is not a memory leak."
exit 0
/*
* Copyright (c) 2010, 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.logging.*;
public class LoggerWeakRefLeak extends SimpleApplication {
// The test driver script will allow this program to run until we
// reach DEFAULT_LOOP_TIME or a decrease in instance counts is
// observed. For these particular WeakReference leaks, the count
// was always observed to be increasing so if we get a decreasing
// count, then the leaks are fixed in the bits being tested.
// Two minutes has been enough time to observe a decrease in
// fixed bits on overloaded systems, but the test will likely
// finish more quickly.
public static int DEFAULT_LOOP_TIME = 120; // time is in seconds
// execute the LoggerWeakRefLeak app work
public void doMyAppWork(String[] args) throws Exception {
int loop_time = 0;
int max_loop_time = DEFAULT_LOOP_TIME;
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default time of "
+ max_loop_time + " seconds.");
} else {
try {
max_loop_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
throw new RuntimeException("Error: '" + args[1]
+ "': is not a valid seconds value.");
}
}
long count = 0;
int loggerCount = 0;
long now = 0;
long startTime = System.currentTimeMillis();
while (now < (startTime + (max_loop_time * 1000))) {
if ((count % 1000) == 0) {
// Print initial call count to let caller know that
// we're up and running and then periodically
System.out.println("INFO: call count = " + count);
}
for (int i = 0; i < 100; i++) {
// This Logger call is leaking two different WeakReferences:
// - one in LogManager.LogNode
// - one in Logger.kids
java.util.logging.Logger.getLogger("logger-" + loggerCount);
count++;
if (++loggerCount >= 25000) {
// Limit the Logger namespace used by the test so
// the weak refs in LogManager.loggers that are
// being properly managed don't skew the counts
// by too much.
loggerCount = 0;
}
}
try {
// delay for 1/10 of a second to avoid CPU saturation
Thread.sleep(100);
} catch (InterruptedException ie) {
// ignore any exceptions
}
now = System.currentTimeMillis();
}
System.out.println("INFO: final loop count = " + count);
}
public static void main(String[] args) throws Exception {
AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}
#!/bin/sh
#
# Copyright (c) 2010, 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.
#
# @test
# @bug 6942989
# @summary Check for WeakReference leak in Logger objects
# @author Daniel D. Daugherty
#
# @library ../../../sun/tools/common
# @build SimpleApplication ShutdownSimpleApplication
# @build LoggerWeakRefLeak
# @run shell/timeout=240 LoggerWeakRefLeak.sh
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
#
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
TEST_NAME="LoggerWeakRefLeak"
TARGET_CLASS="java\.lang\.ref\.WeakReference"
# MAIN begins here
#
seconds=
if [ "$#" -gt 0 ]; then
seconds="$1"
fi
# see if this version of jmap supports the '-histo:live' option
jmap_option="-histo:live"
set +e
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
# usage message doesn't show ':live' option
if $isWindows; then
# If SA isn't present, then jmap gives a different usage message
# that doesn't show the ':live' option. However, that's a bug that
# is covered by 6971851 so we try using the option just to be sure.
# For some reason, this problem has only been seen on OpenJDK6 on
# Windows. Not sure why.
set +e
# Note: Don't copy this code to try probing process 0 on Linux; it
# will kill the process group in strange ways.
"${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
# Usage message generated so flag the problem.
status=1
else
# No usage message so clear the flag.
status=0
fi
fi
if [ "$status" != 0 ]; then
echo "WARNING: 'jmap $jmap_option' is not supported on this platform"
echo "WARNING: so this test cannot work reliably. Aborting!"
exit 0
fi
fi
# Start application and use TEST_NAME.port for coordination
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
finished_early=false
decreasing_cnt=0
increasing_cnt=0
loop_cnt=0
prev_instance_cnt=0
MAX_JMAP_TRY_CNT=10
jmap_retry_cnt=0
loop_cnt_on_retry=0
while true; do
# see if the target process has finished its run and bail if it has
set +e
grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
break
fi
# Output format for 'jmap -histo' in JDK1.5.0:
#
# <#bytes> <#instances> <class_name>
#
# Output format for 'jmap -histo:live':
#
# <num>: <#instances> <#bytes> <class_name>
#
set +e
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
echo "INFO: jmap exited with exit code = $status"
# There are intermittent jmap failures; see 6498448.
#
# So far the following have been observed in a jmap call
# that was not in a race with target process termination:
#
# (Solaris specific, 2nd sample)
# <pid>: Unable to open door: target process not responding or HotSpot VM not loaded
# The -F option can be used when the target process is not responding
#
# (on Solaris so far)
# java.io.IOException
#
# (on Solaris so far, 1st sample)
# <pid>: Permission denied
#
sed 's/^/INFO: /' "$TEST_NAME.jmap"
if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then
# loop count hasn't changed
jmap_retry_cnt=`expr $jmap_retry_cnt + 1`
else
# loop count has changed so remember it
jmap_retry_cnt=1
loop_cnt_on_retry="$loop_cnt"
fi
# This is '-ge' because we have the original attempt plus
# MAX_JMAP_TRY_CNT - 1 retries.
if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then
echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \
"without making any progress."
echo "FAIL: jmap is unable to take any samples." >&2
killApplication
exit 2
fi
# short delay and try again
# Note: sleep 1 didn't help with "<pid>: Permission denied"
sleep 2
echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)."
continue
fi
set +e
instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \
"$TEST_NAME.jmap" \
| sed '
# strip leading whitespace; does nothing in JDK1.5.0
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <#bytes> in JDK1.5.0; does nothing otherwise
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <num>: field; does nothing in JDK1.5.0
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <class_name> field
s/'"${PATTERN_WS}"'.*//
'`
set -e
if [ -z "$instance_cnt" ]; then
echo "INFO: instance count is unexpectedly empty"
if [ "$loop_cnt" = 0 ]; then
echo "INFO: on the first iteration so no sample was found."
echo "INFO: There is likely a problem with the sed filter."
echo "INFO: start of jmap output:"
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
echo "FAIL: cannot find the instance count value." >&2
killApplication
exit 2
fi
else
echo "INFO: instance_cnt = $instance_cnt"
if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then
increasing_cnt=`expr $increasing_cnt + 1`
else
# actually decreasing or the same
decreasing_cnt=`expr $decreasing_cnt + 1`
# For these particular WeakReference leaks, the count was
# always observed to be increasing so if we get a decreasing
# or the same count, then the leaks are fixed in the bits
# being tested.
echo "INFO: finishing early due to non-increasing instance count."
finished_early=true
killApplication
break
fi
prev_instance_cnt="$instance_cnt"
fi
# delay between samples
sleep 5
loop_cnt=`expr $loop_cnt + 1`
done
if [ $finished_early = false ]; then
stopApplication "$TEST_NAME.port"
waitForApplication
fi
echo "INFO: $TEST_NAME has finished running."
echo "INFO: increasing_cnt = $increasing_cnt"
echo "INFO: decreasing_cnt = $decreasing_cnt"
if [ "$jmap_retry_cnt" -gt 0 ]; then
echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)"
fi
if [ "$loop_cnt" = 0 ]; then
echo "FAIL: jmap is unable to take any samples." >&2
exit 2
fi
echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects"
if [ "$decreasing_cnt" = 0 ]; then
echo "INFO: is always increasing."
echo "FAIL: This indicates that there is a memory leak." >&2
exit 2
fi
echo "INFO: is not always increasing."
echo "PASS: This indicates that there is not a memory leak."
exit 0
/*
* Copyright (c) 2010, 2014, 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.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import static jdk.testlibrary.Asserts.assertGreaterThan;
import jdk.testlibrary.ProcessTools;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import sun.tools.attach.HotSpotVirtualMachine;
/*
* @test
* @bug 6942989
* @summary Check for WeakReference leak in Logger and anonymous Logger objects
* @library /lib/testlibrary
* @build jdk.testlibrary.*
* @run main/othervm TestLoggerWeakRefLeak Logger
* @run main/othervm TestLoggerWeakRefLeak AnonymousLogger
*/
public class TestLoggerWeakRefLeak {
private static final String TARGET_CLASS = "java.lang.ref.WeakReference";
private static final int INSTANCE_COUNT = 100;
private static int loggerCount = 0;
public static void main(String[] args) throws Exception {
if (args[0].equals("AnonymousLogger")) {
System.out.println("Test for WeakReference leak in AnonymousLogger object");
testIfLeaking(TestLoggerWeakRefLeak::callAnonymousLogger);
} else {
System.out.println("Test for WeakReference leak in Logger object");
testIfLeaking(TestLoggerWeakRefLeak::callLogger);
}
}
/**
* For these particular WeakReference leaks, the count was always observed
* to be increasing so if decreasing or the same count is observed,
* then there is no leak.
*/
private static void testIfLeaking(Runnable callLogger) throws Exception {
long count = 0;
int instanceCount = 0;
int previousInstanceCount = 0;
int increasingCount = 0;
int decreasingCount = 0;
while (true) {
callLogger.run();
count += INSTANCE_COUNT;
if ((count % 1000) == 0) {
System.out.println("call count = " + count);
instanceCount = getInstanceCountFromHeapHisto();
if (instanceCount > previousInstanceCount) {
increasingCount++;
} else {
decreasingCount++;
System.out.println("increasing count: " + increasingCount);
System.out.println("decreasing or the same count: " + decreasingCount);
System.out.println("Test passed: decreasing or the same instance count is observed");
break;
}
previousInstanceCount = instanceCount;
}
delayExecution();
}
}
/**
* This Logger call is leaking two different WeakReferences:
* - one in LogManager.LogNode
* - one in Logger.kids
*/
private static void callLogger() {
for (int i = 0; i < INSTANCE_COUNT; i++) {
java.util.logging.Logger.getLogger("logger-" + loggerCount);
if (++loggerCount >= 25000) {
// Limit the Logger namespace used by the test so the weak refs
// in LogManager.loggers that are being properly managed
// don't skew the counts by too much.
loggerCount = 0;
}
}
}
/**
* This Logger call is leaking a WeakReference in Logger.kids
*/
private static void callAnonymousLogger() {
for (int i = 0; i < INSTANCE_COUNT; i++) {
java.util.logging.Logger.getAnonymousLogger();
}
}
/**
* 'vm.heapHisto("-live")' will request a full GC
*/
private static int getInstanceCountFromHeapHisto() throws AttachNotSupportedException, Exception {
int instanceCount = 0;
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine
.attach(Integer.toString(ProcessTools.getProcessId()));
try {
try (InputStream heapHistoStream = vm.heapHisto("-live");
BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
if (inputLine.contains(TARGET_CLASS)) {
instanceCount = Integer.parseInt(inputLine
.split("[ ]+")[2]);
System.out.println("instance count: " + instanceCount);
break;
}
}
}
} finally {
vm.detach();
}
assertGreaterThan(instanceCount, 0, "No instances of " + TARGET_CLASS + " are found");
return instanceCount;
}
/**
* Delay for 1/10 of a second to avoid CPU saturation
*/
private static void delayExecution() {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
// Ignore any exceptions
}
}
}
#!/bin/sh
#
# Copyright (c) 2010, 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.
#
# @test
# @bug 6964018
# @summary Unit test for common tools infrastructure.
#
# @build SimpleApplication SleeperApplication ShutdownSimpleApplication
# @run shell CommonTests.sh
. ${TESTSRC}/CommonSetup.sh
. ${TESTSRC}/ApplicationSetup.sh
# hope for the best:
status=0
# Test program path constants from CommonSetup.sh:
#
for name in JAVA JHAT JINFO JMAP JPS JSTACK; do
eval value=$`echo $name`
echo "INFO: $name=$value"
if [ -x "$value" ]; then
echo "INFO: '$value' is executable."
else
echo "ERROR: '$value' is not executable." >&2
status=1
fi
done
# Display flag values from CommonSetup.sh:
#
for name in isCygwin isMKS isLinux isSolaris isUnknownOS isWindows; do
eval value=$`echo $name`
echo "INFO: flag $name=$value"
done
# Test OS constant from CommonSetup.sh:
#
if [ -z "$OS" ]; then
echo "ERROR: OS constant cannot be empty." >&2
status=1
fi
# Display the PATTERN_EOL value:
#
echo "INFO: PATTERN_EOL="`echo "$PATTERN_EOL" | od -c`
# Test PATTERN_EOL with 'grep' for a regular line.
#
TESTOUT="${TESTCLASSES}/testout.grep_reg_line_eol"
set +e
echo 'regular line' | grep "line${PATTERN_EOL}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for regular line with grep."
else
echo "ERROR: PATTERN_EOL does not work for regular line with grep." >&2
status=1
fi
if $isWindows; then
# Test PATTERN_EOL with 'grep' for a CR line.
#
TESTOUT="${TESTCLASSES}/testout.grep_cr_line_eol"
set +e
echo 'CR line ' | grep "line${PATTERN_EOL}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for CR line with grep."
else
echo "ERROR: PATTERN_EOL does not work for CR line with grep." >&2
status=1
fi
fi
# Test PATTERN_EOL with 'sed' for a regular line.
#
TESTOUT="${TESTCLASSES}/testout.sed_reg_line_eol"
echo 'regular line' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for regular line with sed."
else
echo "ERROR: PATTERN_EOL does not work for regular line with sed." >&2
status=1
fi
if $isWindows; then
# Test PATTERN_EOL with 'sed' for a CR line.
#
TESTOUT="${TESTCLASSES}/testout.sed_cr_line_eol"
echo 'CR line ' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for CR line with sed."
else
echo "ERROR: PATTERN_EOL does not work for CR line with sed." >&2
status=1
fi
fi
# Display the PATTERN_WS value:
#
echo "INFO: PATTERN_WS="`echo "$PATTERN_WS" | od -c`
# Test PATTERN_WS with 'grep' for a blank.
#
TESTOUT="${TESTCLASSES}/testout.grep_blank"
set +e
echo 'blank: ' | grep "$PATTERN_WS" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for blanks with grep."
else
echo "ERROR: PATTERN_WS does not work for blanks with grep." >&2
status=1
fi
# Test PATTERN_WS with 'grep' for a tab.
#
TESTOUT="${TESTCLASSES}/testout.grep_tab"
set +e
echo 'tab: ' | grep "$PATTERN_WS" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for tabs with grep."
else
echo "ERROR: PATTERN_WS does not work for tabs with grep." >&2
status=1
fi
# Test PATTERN_WS with 'sed' for a blank.
#
TESTOUT="${TESTCLASSES}/testout.sed_blank"
echo 'blank: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for blanks with sed."
else
echo "ERROR: PATTERN_WS does not work for blanks with sed." >&2
status=1
fi
# Test PATTERN_WS with 'sed' for a tab.
#
TESTOUT="${TESTCLASSES}/testout.sed_tab"
echo 'tab: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for tabs with sed."
else
echo "ERROR: PATTERN_WS does not work for tabs with sed." >&2
status=1
fi
# Test startApplication and use PORTFILE for coordination
# The app sleeps for 30 seconds.
#
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication SleeperApplication "${PORTFILE}" 30
# Test appJavaPid in "ps" cmd output.
#
TESTOUT="${TESTCLASSES}/testout.ps_app"
set +e
if $isCygwin; then
# On Cygwin, appJavaPid is the Windows pid for the Java process
# and appOtherPid is the Cygwin pid for the Java process.
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: begin appJavaPid=$appJavaPid in 'ps' cmd output:"
cat "$TESTOUT"
echo "INFO: end appJavaPid=$appJavaPid in 'ps' cmd output."
else
echo "ERROR: 'ps' cmd should show appJavaPid=$appJavaPid." >&2
status=1
fi
if [ -n "$appOtherPid" ]; then
# Test appOtherPid in "ps" cmd output, if we have one.
#
TESTOUT="${TESTCLASSES}/testout.ps_other"
set +e
if $isCygwin; then
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appOtherPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appOtherPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: begin appOtherPid=$appOtherPid in 'ps' cmd output:"
cat "$TESTOUT"
echo "INFO: end appOtherPid=$appOtherPid in 'ps' cmd output."
else
echo "ERROR: 'ps' cmd should show appOtherPid=$appOtherPid." >&2
status=1
fi
fi
# Test stopApplication and PORTFILE for coordination
#
stopApplication "${PORTFILE}"
# Test application still running after stopApplication.
#
# stopApplication just lets the app know that it can stop, but the
# app might still be doing work. This test just demonstrates that
# fact and doesn't fail if the app is already done.
#
TESTOUT="${TESTCLASSES}/testout.after_stop"
set +e
if $isCygwin; then
# On Cygwin, appJavaPid is the Windows pid for the Java process
# and appOtherPid is the Cygwin pid for the Java process.
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: it is okay for appJavaPid=$appJavaPid to still be running" \
"after stopApplication() is called."
echo "INFO: begin 'after_stop' output:"
cat "$TESTOUT"
echo "INFO: end 'after_stop' output."
fi
# Test waitForApplication
#
# The app might already be gone so this function shouldn't generate
# a fatal error in either call.
#
waitForApplication
if [ $isWindows = false ]; then
# Windows can recycle pids quickly so we can't use this test there
TESTOUT="${TESTCLASSES}/testout.after_kill"
set +e
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "ERROR: 'ps' cmd should not show appJavaPid." >&2
echo "ERROR: begin 'after_kill' output:" >&2
cat "$TESTOUT" >&2
echo "ERROR: end 'after_kill' output." >&2
status=1
else
echo "INFO: 'ps' cmd does not show appJavaPid after" \
"waitForApplication() is called."
fi
fi
# Test killApplication
#
# The app is already be gone so this function shouldn't generate
# a fatal error.
#
killApplication
exit $status
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册