blob: cbdeb8f42037d860a5bb635366a818b121b6e2ea [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
Ian Wienand9573edb2017-03-28 19:37:39 +110017PYTHON=${PYTHON:-python}
18
Ihar Hrachyshka2b4735f2017-02-10 06:17:37 +000019# time to sleep between checks
20SLEEP_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.
26USE_MEM_AVAILABLE=0
27if grep -q '^MemAvailable:' /proc/meminfo; then
28 USE_MEM_AVAILABLE=1
29fi
30
31function get_mem_unevictable {
32 awk '/^Unevictable:/ {print $2}' /proc/meminfo
33}
34
35function 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
46function 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
Ian Wienand9573edb2017-03-28 19:37:39 +110091 ${PYTHON} ./tools/mlock_report.py
Ihar Hrachyshka2b4735f2017-02-10 06:17:37 +000092 fi
93
94 echo "]]]"
95 fi
96 sleep $SLEEP_TIME
97 done
98}
99
100function usage {
101 echo "Usage: $0 [-x] [-s N]" 1>&2
102 exit 1
103}
104
105while 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
117done
118shift $((OPTIND-1))
119
120tracker