aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/mem.py
blob: a4801106b9f3c0271794ae9fed77776ba3f4789f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# -*- python -*-
'''
xpybar – xmobar replacement written in python
Copyright © 2014, 2015, 2016, 2017, 2018, 2019  Mattias Andrée (maandree@kth.se)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''


class Memory:
    '''
    Retrieve memory information
    
    @variable  mem_total:int            Total usable RAM (physical RAM minus a few reserved bit, in KB
                                        minus kernel binary code), in KB
    @variable  mem_free:int             Amount of unused usable physical RAM, in KB
    @variable  mem_used:int             Amount of used usable physical RAM, in KB
    @variable  buffers:int              Relatively temporary storage for raw disc blocks, in KB
    @variable  cached:int               In-memory cache for files read from the disc (the pagecache), in KB.
                                        Does not include swap_cached.
    @variable  swap_cached:int          Memory that once was swapped out, is swapped back in but still
                                        also is in the swapfile, in KB
    @variable  swap_total:int           Total amount of swap space available, in KB
    @variable  swap_free:int            Amount of unused swap space available, in KB
    @variable  swap_used:int            Memory which has been evicted from RAM to swap space, in KB
    @variable  shmem:int?               Amount of memory allocated as shared memory, in KB
    @variable  slab:int?                In-kernel data structures cache, in KB
    @variable  hardware_corrupted:int?  Hardware corrupted memory, in KB
    @variable  keys:frozenset           List of all keys
    '''
    
    
    def __init__(self):
        '''
        Constructor
        '''
        meminfo = None
        with open('/proc/meminfo', 'rb') as file:
            meminfo = file.read()
        meminfo = meminfo.decode('utf-8', 'replace')
        meminfo = filter(lambda x : not x == '', meminfo.split('\n'))
        
        self.__info = {}
        for line in meminfo:
            line = filter(lambda x : not x == '', line.replace(':', ' ').split(' '))
            line = list(line)[:2]
            self.__info[line[0]] = int(line[1])
        
        self.keys = self.__info.keys()
        
        self.mem_total = self['MemTotal']
        self.buffers = self['Buffers']
        self.cached = self['Cached']
        self.mem_free = self['MemFree'] + self.buffers + self.cached + self.get('KReclaimable', self.get('SReclaimable'))
        self.mem_used = self.mem_total - self.mem_free
        self.swap_cached = self['SwapCached']
        self.swap_total = self['SwapTotal']
        self.swap_free = self['SwapFree']
        self.swap_used = self.swap_total - (self.swap_free + self.swap_cached)
        self.shmem = self.get('Shmem', None)
        self.slab = self.get('Slab', None)
        self.hardware_corrupted = self.get('HardwareCorrupted', None)
    
    
    def __contains__(self, key):
        '''
        Get whether or not a key is available
        
        @param   key:str  The key
        @return  :bool    The availability
        '''
        return key in self.__info


    def get(self, key, default = 0):
        '''
        Look up a field from '/proc/meminfo'
        
        @param   key:str      The field name
        @param   default:int  The value to return if the field does not exist
        @return  :int         The value of the field, without the unit (KB if any)
        
        This keys should be available, but are most probably more available:
        
        @key  MemTotal           Total usable RAM (physical RAM minus a few reserved bit minus kernel binary code)
        @key  MemFree            Amount of unused usable physical RAM
        @key  MemAvailable       An estimate of how much memory is available for starting new applications, without swapping
        @key  Buffers            Relatively temporary storage for raw disc blocks
        @key  Cached             In-memory cache for files read from the disc (the pagecache).
                                 Does not include SwapCached.
        @key  SwapCached         Memory that once was swapped out, is swapped
                                 back in but still also is in the swapfile
        @key  Active             Memory that has been used more recently and
                                 usually not reclaimed unless absolutely necessary
        @key  Inactive           Memory which has been less recently used. It is
                                 more eligible to be reclaimed for other purposes
        @key  Active(anon)       [To be documented.]
        @key  Inactive(anon)     [To be documented.]
        @key  Active(file)       [To be documented.]
        @key  Inactive(file)     [To be documented.]
        @key  Unevictable        [To be documented.]
        @key  Mlocked            [To be documented.]
        @key  HighTotal          Total amount of highmem. Highmem is all memory above ~860MB of physical
                                 memory. Highmem areas are for use by user-space programs, or for the page
                                 cache. The kernel must use tricks to access this memory, making it slower
                                 to access than lowmem.
        @key  HighFree           Amount of free highmem
        @key  LowTotal           Total amount of lowmem. Lowmem is memory which can be used for everything
                                 that highmem can be used for, but it is also available for the kernel's use
                                 for its own data structures. Among many other things, it is where everything
                                 from Slab is allocated. Bad things happen when you're out of lowmem.
        @key  LowFree            Amount of free lowmem
        @key  MmapCopy           [To be documented.]
        @key  SwapTotal          Total amount of swap space available
        @key  SwapFree           Amount of unused swap space available
        @key  Dirty              Memory which is waiting to get written back to the disc
        @key  Writeback          Memory which is actively being written back to the disc
        @key  AnonPages          Non-file backed pages mapped into userspace page tables
        @key  Mapped             Files which have been mmaped, such as libraries
        @key  Shmem              Amount of memory consumed in tmpfs(5) filesystems
        @key  KReclaimable       Kernel allocations that the kernel will attempt to reclaim under memory
                                 pressure. Includes SReclaimable, and other direct allocations with a shrinker.
        @key  Slab               In-kernel data structures cache
        @key  SReclaimable       Part of Slab, that might be reclaimed, such as caches
        @key  SUnreclaim         Part of Slab, that cannot be reclaimed on memory pressure
        @key  KernelStack        Amount of memory allocated to kernel stacks
        @key  PageTables         Amount of memory dedicated to the lowest level of page tables
        @key  Quicklists         [To be documented.]
        @key  NFS_Unstable       NFS pages sent to the server, but not yet committed to stable storage
        @key  Bounce             Memory used for block device “bounce buffers”
        @key  WritebackTmp       Memory used by FUSE for temporary writeback buffers
        @key  CommitLimit        The total amount of memory currently available to be allocated
                                 on the system. Based on overcommit ratio.
        @key  Committed_AS       The amount of memory presently allocated on the system.
        @key  VmallocTotal       Total size of vmalloc memory area
        @key  VmallocUsed        Amount of vmalloc area which is used
        @key  VmallocChunk       Largest contiguous block of vmalloc area which is free
        @key  Percpu             [To be documented.]
        @key  HardwareCorrupted  [To be documented.]
        @key  LazyFree           Shows the amount of memory marked by madvise(2) MADV_FREE
        @key  AnonHugePages      Non-file backed huge pages mapped into userspace page tables
        @key  ShmemHugePages     Memory used by shared memory (shmem) and tmpfs(5) allocated with huge pages
        @key  ShmemPmdMapped     Shared memory mapped into user space with huge pages
        @key  CmaTotal           Total CMA (Contiguous Memory Allocator) pages
        @key  CmaFree            Free CMA (Contiguous Memory Allocator) pages
        @key  HugePages_Total    The size of the pool of huge pages
        @key  HugePages_Free     The number of huge pages in the pool that are not yet allocated
        @key  HugePages_Rsvd     This is the number of huge pages for which a commitment to allocate from
                                 the pool has been made, but no allocation has yet been made. These reserved
                                 huge pages guarantee that an application will be able to allocate a huge
                                 page from the pool of huge pages at fault time
        @key  HugePages_Surp     This is the number of huge pages in the pool above the value in
                                 /proc/sys/vm/nr_hugepages. The maximum number of surplus huge pages is
                                 controlled by /proc/sys/vm/nr_overcommit_hugepages.
        @key  Hugepagesize       The size of huge pages
        @key  Hugetlb            [To be documented.]
        @key  DirectMap4k        Number of bytes of RAM linearly mapped by kernel in 4kB pages
        @key  DirectMap2M        Number of bytes of RAM linearly mapped by kernel in 2MB pages
        @key  DirectMap4M        Number of bytes of RAM linearly mapped by kernel in 4MB pages
        @key  DirectMap1G        Number of bytes of RAM linearly mapped by kernel in 1GB pages
        '''
        return self.__info.get(key, default)


    def __getitem__(self, key):
        '''
        Equivalent to `self.get(key)`, except
        it fails rather than return 0 if the
        field does not exist
        '''
        return self.__info[key]