| Ian Wienand | 72a8be6 | 2015-04-09 13:51:23 +1000 | [diff] [blame] | 1 | #!/bin/bash | 
 | 2 | # | 
 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | 
 | 4 | # not use this file except in compliance with the License. You may obtain | 
 | 5 | # a copy of the License at | 
 | 6 | # | 
 | 7 | #    http://www.apache.org/licenses/LICENSE-2.0 | 
 | 8 | # | 
 | 9 | # Unless required by applicable law or agreed to in writing, software | 
 | 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
 | 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
 | 12 | # License for the specific language governing permissions and limitations | 
 | 13 | # under the License. | 
 | 14 |  | 
 | 15 | set -o errexit | 
 | 16 |  | 
 | 17 | # time to sleep between checks | 
 | 18 | SLEEP_TIME=20 | 
 | 19 |  | 
 | 20 | # MemAvailable is the best estimation and has built-in heuristics | 
 | 21 | # around reclaimable memory.  However, it is not available until 3.14 | 
 | 22 | # kernel (i.e. Ubuntu LTS Trusty misses it).  In that case, we fall | 
 | 23 | # back to free+buffers+cache as the available memory. | 
 | 24 | USE_MEM_AVAILBLE=0 | 
 | 25 | if grep -q '^MemAvailable:' /proc/meminfo; then | 
 | 26 |     USE_MEM_AVAILABLE=1 | 
 | 27 | fi | 
 | 28 |  | 
 | 29 | function get_mem_available { | 
 | 30 |     if [[ $USE_MEM_AVAILABLE -eq 1 ]]; then | 
 | 31 |         awk '/^MemAvailable:/ {print $2}' /proc/meminfo | 
 | 32 |     else | 
 | 33 |         awk '/^MemFree:/ {free=$2} | 
 | 34 |             /^Buffers:/ {buffers=$2} | 
 | 35 |             /^Cached:/  {cached=$2} | 
 | 36 |             END { print free+buffers+cached }' /proc/meminfo | 
 | 37 |     fi | 
 | 38 | } | 
 | 39 |  | 
 | 40 | # whenever we see less memory available than last time, dump the | 
 | 41 | # snapshot of current usage; i.e. checking the latest entry in the | 
 | 42 | # file will give the peak-memory usage | 
 | 43 | function tracker { | 
| Ian Wienand | ada886d | 2015-10-07 14:06:26 +1100 | [diff] [blame] | 44 |     local low_point | 
 | 45 |     low_point=$(get_mem_available) | 
| Ian Wienand | 72a8be6 | 2015-04-09 13:51:23 +1000 | [diff] [blame] | 46 |     while [ 1 ]; do | 
 | 47 |  | 
| Ian Wienand | ada886d | 2015-10-07 14:06:26 +1100 | [diff] [blame] | 48 |         local mem_available | 
 | 49 |         mem_available=$(get_mem_available) | 
| Ian Wienand | 72a8be6 | 2015-04-09 13:51:23 +1000 | [diff] [blame] | 50 |  | 
 | 51 |         if [[ $mem_available -lt $low_point ]]; then | 
 | 52 |             low_point=$mem_available | 
 | 53 |             echo "[[[" | 
 | 54 |             date | 
 | 55 |             echo "---" | 
 | 56 |             # always available greppable output; given difference in | 
 | 57 |             # meminfo output as described above... | 
 | 58 |             echo "peakmem_tracker low_point: $mem_available" | 
 | 59 |             echo "---" | 
 | 60 |             cat /proc/meminfo | 
 | 61 |             echo "---" | 
 | 62 |             # would hierarchial view be more useful (-H)?  output is | 
 | 63 |             # not sorted by usage then, however, and the first | 
 | 64 |             # question is "what's using up the memory" | 
 | 65 |             # | 
 | 66 |             # there are a lot of kernel threads, especially on a 8-cpu | 
 | 67 |             # system.  do a best-effort removal to improve | 
 | 68 |             # signal/noise ratio of output. | 
 | 69 |             ps --sort=-pmem -eo pid:10,pmem:6,rss:15,ppid:10,cputime:10,nlwp:8,wchan:25,args:100 | | 
 | 70 |                 grep -v ']$' | 
 | 71 |             echo "]]]" | 
 | 72 |         fi | 
 | 73 |  | 
 | 74 |         sleep $SLEEP_TIME | 
 | 75 |     done | 
 | 76 | } | 
 | 77 |  | 
 | 78 | function usage { | 
 | 79 |     echo "Usage: $0 [-x] [-s N]" 1>&2 | 
 | 80 |     exit 1 | 
 | 81 | } | 
 | 82 |  | 
 | 83 | while getopts ":s:x" opt; do | 
 | 84 |     case $opt in | 
 | 85 |         s) | 
 | 86 |             SLEEP_TIME=$OPTARG | 
 | 87 |             ;; | 
 | 88 |         x) | 
 | 89 |             set -o xtrace | 
 | 90 |             ;; | 
 | 91 |         *) | 
 | 92 |             usage | 
 | 93 |             ;; | 
 | 94 |     esac | 
 | 95 | done | 
 | 96 | shift $((OPTIND-1)) | 
 | 97 |  | 
 | 98 | tracker |