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