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 # @ignore until 6964018 is fixed 27 # @summary Check for WeakReference leak in anonymous Logger objects 28 # @author Daniel D. Daugherty 29 # 30 # @run build AnonLoggerWeakRefLeak 31 # @run shell/timeout=180 AnonLoggerWeakRefLeak.sh 32 33 # The timeout is: 2 minutes for infrastructure and 1 minute for the test 34 # 35 36 if [ "${TESTJAVA}" = "" ] 37 then 38 echo "TESTJAVA not set. Test cannot execute. Failed." 39 exit 1 40 fi 41 42 if [ "${TESTSRC}" = "" ] 43 then 44 echo "TESTSRC not set. Test cannot execute. Failed." 45 exit 1 46 fi 47 48 if [ "${TESTCLASSES}" = "" ] 49 then 50 echo "TESTCLASSES not set. Test cannot execute. Failed." 51 exit 1 52 fi 53 54 JAVA="${TESTJAVA}"/bin/java 55 JMAP="${TESTJAVA}"/bin/jmap 56 JPS="${TESTJAVA}"/bin/jps 57 58 set -eu 59 60 TEST_NAME="AnonLoggerWeakRefLeak" 61 TARGET_CLASS="java\.lang\.ref\.WeakReference" 62 63 is_cygwin=false 64 is_mks=false 65 is_windows=false 66 67 case `uname -s` in 68 CYGWIN*) 69 is_cygwin=true 70 is_windows=true 71 ;; 72 Windows_*) 73 is_mks=true 74 is_windows=true 75 ;; 76 *) 77 ;; 78 esac 79 80 81 # wrapper for grep 82 # 83 grep_cmd() { 84 set +e 85 if $is_windows; then 86 # need dos2unix to get rid of CTRL-M chars from java output 87 dos2unix | grep "$@" 88 status="$?" 89 else 90 grep "$@" 91 status="$?" 92 fi 93 set -e 94 } 95 96 97 # MAIN begins here 98 # 99 100 seconds= 101 if [ "$#" -gt 0 ]; then 102 seconds="$1" 103 fi 104 105 # see if this version of jmap supports the '-histo:live' option 106 jmap_option="-histo:live" 107 set +e 108 "${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1 109 grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1 110 status="$?" 111 set -e 112 if [ "$status" = 0 ]; then 113 echo "INFO: switching jmap option from '$jmap_option'\c" 114 jmap_option="-histo" 115 echo " to '$jmap_option'." 116 fi 117 118 "${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \ 119 "$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 & 120 test_pid="$!" 121 echo "INFO: starting $TEST_NAME as pid = $test_pid" 122 123 # wait for test program to get going 124 count=0 125 while [ "$count" -lt 30 ]; do 126 sleep 2 127 grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1 128 if [ "$status" = 0 ]; then 129 break 130 fi 131 count=`expr $count + 1` 132 done 133 134 if [ "$count" -ge 30 ]; then 135 echo "ERROR: $TEST_NAME failed to get going." >&2 136 echo "INFO: killing $test_pid" 137 kill "$test_pid" 138 exit 1 139 elif [ "$count" -gt 1 ]; then 140 echo "INFO: $TEST_NAME took $count loops to start." 141 fi 142 143 if $is_cygwin; then 144 # We need the Windows pid for jmap and not the Cygwin pid. 145 # Note: '\t' works on Cygwin, but doesn't seem to work on Solaris. 146 jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'` 147 if [ -z "$jmap_pid" ]; then 148 echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2 149 echo "INFO: killing $test_pid" 150 kill "$test_pid" 151 exit 2 152 fi 153 echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid" 154 else 155 jmap_pid="$test_pid" 156 fi 157 158 decreasing_cnt=0 159 increasing_cnt=0 160 loop_cnt=0 161 prev_instance_cnt=0 162 163 while true; do 164 # Output format for 'jmap -histo' in JDK1.5.0: 165 # 166 # <#bytes> <#instances> <class_name> 167 # 168 # Output format for 'jmap -histo:live': 169 # 170 # <num>: <#instances> <#bytes> <class_name> 171 # 172 set +e 173 "${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1 174 status="$?" 175 set -e 176 177 if [ "$status" != 0 ]; then 178 echo "INFO: jmap exited with exit code = $status" 179 if [ "$loop_cnt" = 0 ]; then 180 echo "INFO: on the first iteration so no samples were taken." 181 echo "INFO: start of jmap output:" 182 cat "$TEST_NAME.jmap" 183 echo "INFO: end of jmap output." 184 echo "FAIL: jmap is unable to take any samples." >&2 185 echo "INFO: killing $test_pid" 186 kill "$test_pid" 187 exit 2 188 fi 189 echo "INFO: The likely reason is that $TEST_NAME has finished running." 190 break 191 fi 192 193 instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \ 194 < "$TEST_NAME.jmap" \ 195 | sed ' 196 # strip leading whitespace; does nothing in JDK1.5.0 197 s/^[ ][ ]*// 198 # strip <#bytes> in JDK1.5.0; does nothing otherwise 199 s/^[1-9][0-9]*[ ][ ]*// 200 # strip <num>: field; does nothing in JDK1.5.0 201 s/^[1-9][0-9]*:[ ][ ]*// 202 # strip <class_name> field 203 s/[ ].*// 204 '` 205 if [ -z "$instance_cnt" ]; then 206 echo "INFO: instance count is unexpectedly empty" 207 if [ "$loop_cnt" = 0 ]; then 208 echo "INFO: on the first iteration so no sample was found." 209 echo "INFO: There is likely a problem with the sed filter." 210 echo "INFO: start of jmap output:" 211 cat "$TEST_NAME.jmap" 212 echo "INFO: end of jmap output." 213 echo "FAIL: cannot find the instance count value." >&2 214 echo "INFO: killing $test_pid" 215 kill "$test_pid" 216 exit 2 217 fi 218 else 219 echo "INFO: instance_cnt = $instance_cnt" 220 221 if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then 222 increasing_cnt=`expr $increasing_cnt + 1` 223 else 224 decreasing_cnt=`expr $decreasing_cnt + 1` 225 fi 226 prev_instance_cnt="$instance_cnt" 227 fi 228 229 # delay between samples 230 sleep 5 231 232 loop_cnt=`expr $loop_cnt + 1` 233 done 234 235 echo "INFO: increasing_cnt = $increasing_cnt" 236 echo "INFO: decreasing_cnt = $decreasing_cnt" 237 238 echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" 239 if [ "$decreasing_cnt" = 0 ]; then 240 echo "INFO: is always increasing." 241 echo "FAIL: This indicates that there is a memory leak." >&2 242 exit 2 243 fi 244 245 echo "INFO: is both increasing and decreasing." 246 echo "PASS: This indicates that there is not a memory leak." 247 exit 0