1 # 2 # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 # 5 # This code is free software; you can redistribute it and/or modify it 6 # under the terms of the GNU General Public License version 2 only, as 7 # published by the Free Software Foundation. 8 # 9 # This code is distributed in the hope that it will be useful, but WITHOUT 10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 # version 2 for more details (a copy is included in the LICENSE file that 13 # accompanied this code). 14 # 15 # You should have received a copy of the GNU General Public License version 16 # 2 along with this work; if not, write to the Free Software Foundation, 17 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 # 19 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 # or visit www.oracle.com if you need additional information or have any 21 # questions. 22 # 23 24 # @test 25 # @bug 6942989 26 # @summary Check for WeakReference leak in anonymous Logger objects 27 # @author Daniel D. Daugherty 28 # 29 # @run build AnonLoggerWeakRefLeak 30 # @run shell/timeout=180 AnonLoggerWeakRefLeak.sh 31 32 # The timeout is: 2 minutes for infrastructure and 1 minute for the test 33 # 34 35 if [ "${TESTJAVA}" = "" ] 36 then 37 echo "TESTJAVA not set. Test cannot execute. Failed." 38 exit 1 39 fi 40 41 if [ "${TESTSRC}" = "" ] 42 then 43 echo "TESTSRC not set. Test cannot execute. Failed." 44 exit 1 45 fi 46 47 if [ "${TESTCLASSES}" = "" ] 48 then 49 echo "TESTCLASSES not set. Test cannot execute. Failed." 50 exit 1 51 fi 52 53 JAVA="${TESTJAVA}"/bin/java 54 JMAP="${TESTJAVA}"/bin/jmap 55 JPS="${TESTJAVA}"/bin/jps 56 57 set -eu 58 59 TEST_NAME="AnonLoggerWeakRefLeak" 60 TARGET_CLASS="java\.lang\.ref\.WeakReference" 61 62 is_cygwin=false 63 is_mks=false 64 is_windows=false 65 66 case `uname -s` in 67 CYGWIN*) 68 is_cygwin=true 69 is_windows=true 70 ;; 71 Windows_*) 72 is_mks=true 73 is_windows=true 74 ;; 75 *) 76 ;; 77 esac 78 79 80 # wrapper for grep 81 # 82 grep_cmd() { 83 set +e 84 if $is_windows; then 85 # need dos2unix to get rid of CTRL-M chars from java output 86 dos2unix | grep "$@" 87 status="$?" 88 else 89 grep "$@" 90 status="$?" 91 fi 92 set -e 93 } 94 95 96 # MAIN begins here 97 # 98 99 seconds= 100 if [ "$#" -gt 0 ]; then 101 seconds="$1" 102 fi 103 104 # see if this version of jmap supports the '-histo:live' option 105 jmap_option="-histo:live" 106 set +e 107 "${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1 108 grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1 109 status="$?" 110 set -e 111 if [ "$status" = 0 ]; then 112 echo "INFO: switching jmap option from '$jmap_option'\c" 113 jmap_option="-histo" 114 echo " to '$jmap_option'." 115 fi 116 117 "${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \ 118 "$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 & 119 test_pid="$!" 120 echo "INFO: starting $TEST_NAME as pid = $test_pid" 121 122 # wait for test program to get going 123 count=0 124 while [ "$count" -lt 30 ]; do 125 sleep 2 126 grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1 127 if [ "$status" = 0 ]; then 128 break 129 fi 130 count=`expr $count + 1` 131 done 132 133 if [ "$count" -ge 30 ]; then 134 echo "ERROR: $TEST_NAME failed to get going." >&2 135 echo "INFO: killing $test_pid" 136 kill "$test_pid" 137 exit 1 138 elif [ "$count" -gt 1 ]; then 139 echo "INFO: $TEST_NAME took $count loops to start." 140 fi 141 142 if $is_cygwin; then 143 # We need the Windows pid for jmap and not the Cygwin pid. 144 # Note: '\t' works on Cygwin, but doesn't seem to work on Solaris. 145 jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'` 146 if [ -z "$jmap_pid" ]; then 147 echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2 148 echo "INFO: killing $test_pid" 149 kill "$test_pid" 150 exit 2 151 fi 152 echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid" 153 else 154 jmap_pid="$test_pid" 155 fi 156 157 decreasing_cnt=0 158 increasing_cnt=0 159 loop_cnt=0 160 prev_instance_cnt=0 161 162 while true; do 163 # Output format for 'jmap -histo' in JDK1.5.0: 164 # 165 # <#bytes> <#instances> <class_name> 166 # 167 # Output format for 'jmap -histo:live': 168 # 169 # <num>: <#instances> <#bytes> <class_name> 170 # 171 set +e 172 "${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1 173 status="$?" 174 set -e 175 176 if [ "$status" != 0 ]; then 177 echo "INFO: jmap exited with exit code = $status" 178 if [ "$loop_cnt" = 0 ]; then 179 echo "INFO: on the first iteration so no samples were taken." 180 echo "INFO: start of jmap output:" 181 cat "$TEST_NAME.jmap" 182 echo "INFO: end of jmap output." 183 echo "FAIL: jmap is unable to take any samples." >&2 184 echo "INFO: killing $test_pid" 185 kill "$test_pid" 186 exit 2 187 fi 188 echo "INFO: The likely reason is that $TEST_NAME has finished running." 189 break 190 fi 191 192 instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \ 193 < "$TEST_NAME.jmap" \ 194 | sed ' 195 # strip leading whitespace; does nothing in JDK1.5.0 196 s/^[ ][ ]*// 197 # strip <#bytes> in JDK1.5.0; does nothing otherwise 198 s/^[1-9][0-9]*[ ][ ]*// 199 # strip <num>: field; does nothing in JDK1.5.0 200 s/^[1-9][0-9]*:[ ][ ]*// 201 # strip <class_name> field 202 s/[ ].*// 203 '` 204 if [ -z "$instance_cnt" ]; then 205 echo "INFO: instance count is unexpectedly empty" 206 if [ "$loop_cnt" = 0 ]; then 207 echo "INFO: on the first iteration so no sample was found." 208 echo "INFO: There is likely a problem with the sed filter." 209 echo "INFO: start of jmap output:" 210 cat "$TEST_NAME.jmap" 211 echo "INFO: end of jmap output." 212 echo "FAIL: cannot find the instance count value." >&2 213 echo "INFO: killing $test_pid" 214 kill "$test_pid" 215 exit 2 216 fi 217 else 218 echo "INFO: instance_cnt = $instance_cnt" 219 220 if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then 221 increasing_cnt=`expr $increasing_cnt + 1` 222 else 223 decreasing_cnt=`expr $decreasing_cnt + 1` 224 fi 225 prev_instance_cnt="$instance_cnt" 226 fi 227 228 # delay between samples 229 sleep 5 230 231 loop_cnt=`expr $loop_cnt + 1` 232 done 233 234 echo "INFO: increasing_cnt = $increasing_cnt" 235 echo "INFO: decreasing_cnt = $decreasing_cnt" 236 237 echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" 238 if [ "$decreasing_cnt" = 0 ]; then 239 echo "INFO: is always increasing." 240 echo "FAIL: This indicates that there is a memory leak." >&2 241 exit 2 242 fi 243 244 echo "INFO: is both increasing and decreasing." 245 echo "PASS: This indicates that there is not a memory leak." 246 exit 0