| Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [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 |  | 
| Ian Wienand | 9573edb | 2017-03-28 19:37:39 +1100 | [diff] [blame] | 17 | PYTHON=${PYTHON:-python} | 
|  | 18 |  | 
| Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 19 | # time to sleep between checks | 
|  | 20 | SLEEP_TIME=20 | 
|  | 21 |  | 
|  | 22 | # MemAvailable is the best estimation and has built-in heuristics | 
|  | 23 | # around reclaimable memory.  However, it is not available until 3.14 | 
|  | 24 | # kernel (i.e. Ubuntu LTS Trusty misses it).  In that case, we fall | 
|  | 25 | # back to free+buffers+cache as the available memory. | 
|  | 26 | USE_MEM_AVAILABLE=0 | 
|  | 27 | if grep -q '^MemAvailable:' /proc/meminfo; then | 
|  | 28 | USE_MEM_AVAILABLE=1 | 
|  | 29 | fi | 
|  | 30 |  | 
|  | 31 | function get_mem_unevictable { | 
|  | 32 | awk '/^Unevictable:/ {print $2}' /proc/meminfo | 
|  | 33 | } | 
|  | 34 |  | 
|  | 35 | function get_mem_available { | 
|  | 36 | if [[ $USE_MEM_AVAILABLE -eq 1 ]]; then | 
|  | 37 | awk '/^MemAvailable:/ {print $2}' /proc/meminfo | 
|  | 38 | else | 
|  | 39 | awk '/^MemFree:/ {free=$2} | 
|  | 40 | /^Buffers:/ {buffers=$2} | 
|  | 41 | /^Cached:/  {cached=$2} | 
|  | 42 | END { print free+buffers+cached }' /proc/meminfo | 
|  | 43 | fi | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | function tracker { | 
|  | 47 | local low_point | 
|  | 48 | local unevictable_point | 
|  | 49 | low_point=$(get_mem_available) | 
|  | 50 | # log mlocked memory at least on first iteration | 
|  | 51 | unevictable_point=0 | 
|  | 52 | while [ 1 ]; do | 
|  | 53 |  | 
|  | 54 | local mem_available | 
|  | 55 | mem_available=$(get_mem_available) | 
|  | 56 |  | 
|  | 57 | local unevictable | 
|  | 58 | unevictable=$(get_mem_unevictable) | 
|  | 59 |  | 
|  | 60 | if [ $mem_available -lt $low_point -o $unevictable -ne $unevictable_point ]; then | 
|  | 61 | echo "[[[" | 
|  | 62 | date | 
|  | 63 |  | 
|  | 64 | # whenever we see less memory available than last time, dump the | 
|  | 65 | # snapshot of current usage; i.e. checking the latest entry in the file | 
|  | 66 | # will give the peak-memory usage | 
|  | 67 | if [[ $mem_available -lt $low_point ]]; then | 
|  | 68 | low_point=$mem_available | 
|  | 69 | echo "---" | 
|  | 70 | # always available greppable output; given difference in | 
|  | 71 | # meminfo output as described above... | 
|  | 72 | echo "memory_tracker low_point: $mem_available" | 
|  | 73 | echo "---" | 
|  | 74 | cat /proc/meminfo | 
|  | 75 | echo "---" | 
|  | 76 | # would hierarchial view be more useful (-H)?  output is | 
|  | 77 | # not sorted by usage then, however, and the first | 
|  | 78 | # question is "what's using up the memory" | 
|  | 79 | # | 
|  | 80 | # there are a lot of kernel threads, especially on a 8-cpu | 
|  | 81 | # system.  do a best-effort removal to improve | 
|  | 82 | # signal/noise ratio of output. | 
|  | 83 | ps --sort=-pmem -eo pid:10,pmem:6,rss:15,ppid:10,cputime:10,nlwp:8,wchan:25,args:100 | | 
|  | 84 | grep -v ']$' | 
|  | 85 | fi | 
|  | 86 | echo "---" | 
|  | 87 |  | 
|  | 88 | # list processes that lock memory from swap | 
|  | 89 | if [[ $unevictable -ne $unevictable_point ]]; then | 
|  | 90 | unevictable_point=$unevictable | 
| Vasyl Saienko | dea3083 | 2017-08-01 00:16:51 +0300 | [diff] [blame] | 91 | ${PYTHON} $(dirname $0)/mlock_report.py | 
| Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 92 | fi | 
|  | 93 |  | 
|  | 94 | echo "]]]" | 
|  | 95 | fi | 
|  | 96 | sleep $SLEEP_TIME | 
|  | 97 | done | 
|  | 98 | } | 
|  | 99 |  | 
|  | 100 | function usage { | 
|  | 101 | echo "Usage: $0 [-x] [-s N]" 1>&2 | 
|  | 102 | exit 1 | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | while getopts ":s:x" opt; do | 
|  | 106 | case $opt in | 
|  | 107 | s) | 
|  | 108 | SLEEP_TIME=$OPTARG | 
|  | 109 | ;; | 
|  | 110 | x) | 
|  | 111 | set -o xtrace | 
|  | 112 | ;; | 
|  | 113 | *) | 
|  | 114 | usage | 
|  | 115 | ;; | 
|  | 116 | esac | 
|  | 117 | done | 
|  | 118 | shift $((OPTIND-1)) | 
|  | 119 |  | 
|  | 120 | tracker |