79

How can I get the total physical memory within Python in a distribution agnostic fashion? I don't need used memory, just the total physical memory.

6
  • You could read /proc/meminfo.
    – Lee Duhem
    Commented Feb 28, 2014 at 18:30
  • /proc/meminfo should be available on pretty much all linux installs.
    – Marc B
    Commented Feb 28, 2014 at 18:30
  • 1
    You don't need /proc/meminfo because sysconf has the answer.
    – Asclepius
    Commented Jan 27, 2015 at 20:13
  • /proc is only available when CONFIG_PROC_FS=y . True for desktops, servers, phones, not always true for embedded devices.
    – rsaxvc
    Commented Jul 16, 2016 at 15:06
  • 1
    You rarely should care about physical memory (imagine for example a virtual processor thru docker etc...) Commented Aug 27, 2017 at 19:33

4 Answers 4

104

your best bet for a cross-platform solution is to use the psutil package (available on PyPI).

import psutil
    
psutil.virtual_memory().total  # total physical memory in Bytes

Documentation for virtual_memory is here.

4
  • 1
    mem = virtual_memory() and then # total physical memory? Sounds great Commented Aug 30, 2018 at 18:44
  • Future proofed with 2018/12/18: web.archive.org/web/20181228093919/https://… Commented Jan 2, 2019 at 17:17
  • int(np.round(psutil.virtual_memory().total / (1024. **3))) with a tip from @Asclepius. Commented Feb 1, 2023 at 4:37
  • total does not (always?) seem to return the total physical memory available. E.g. getting 33429086208 for a 32 GB machine. Expected (as reported by free): 34359738368
    – Joerg S
    Commented Jan 18 at 14:24
76

Using os.sysconf on Linux:

import os
mem_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')  # e.g. 4015976448
mem_gib = mem_bytes/(1024.**3)  # e.g. 3.74

Note:

  • SC_PAGE_SIZE is often 4096.
  • SC_PAGESIZE and SC_PAGE_SIZE are equal.
  • For more info, see man sysconf.
  • For MacOS, as per user reports, this works with Python 3.7 but not with Python 3.8.

Using /proc/meminfo on Linux:

meminfo = dict((i.split()[0].rstrip(':'),int(i.split()[1])) for i in open('/proc/meminfo').readlines())
mem_kib = meminfo['MemTotal']  # e.g. 3921852
7
  • 1
    @sorin, os.sysconf('SC_PHYS_PAGES') apparently doesn't work on OS X. Although the OS X man page for sysconf does make note of _SC_PHYS_PAGES, this seems inaccessible via Python. You may have more luck with psutil. Alternatively, refer to the techniques used in the answers here.
    – Asclepius
    Commented Jul 17, 2015 at 18:58
  • 2
    FWIW, the os.sysconf() approach also works with Python 3 and even under Solaris 10. Commented Aug 27, 2017 at 19:25
  • 1
    I am happy to report that it's working on MacOS X 10.13 (High Sierra) with Python 3.6.4. Commented Apr 19, 2018 at 16:49
  • 1
    On MacOs, works fine on Python 3.7 but not on Python 3.8.3. Getting ValueError: unrecognized configuration name for os.sysconf('SC_PHYS_PAGES') Commented Jun 26, 2020 at 18:40
  • 1
    Ideally I would want to figure out how to do this without external dependencies such as psutil Commented Jun 27, 2020 at 1:09
14

Regular expressions work well for this sort of thing, and might help with any minor differences across distributions.

import re
with open('/proc/meminfo') as f:
    meminfo = f.read()
matched = re.search(r'^MemTotal:\s+(\d+)', meminfo)
if matched: 
    mem_total_kB = int(matched.groups()[0])
5
  • 5
    /proc only exists on Linux... so not cross-platform Commented Apr 30, 2017 at 1:03
  • I mistook distribution-agnostic for cross-platform... and now I see it's tagged Linux. my bad :) Commented Jun 21, 2018 at 0:19
  • /proc/meminfo seems not to work as expected on AWS: Why does /proc/meminfo show 32GB when AWS instance has only 16GB? Commented Apr 29, 2020 at 11:16
  • 1
    @JoshuaDetwiler You don't need to explicitly close files when using contexts like this. When the context (the with block) is closed the file will be with it. Commented Feb 12, 2021 at 15:08
  • Also @martin-thoma What AWS image are you using, I do not have this issue with the latest amazonlinux2. Commented Feb 12, 2021 at 15:11
0

This code worked for me without any external library at Python 2.7.9

import os
mem=str(os.popen('free -t -m').readlines())
"""
Get a whole line of memory output, it will be something like below
['             total       used       free     shared    buffers     cached\n', 
'Mem:           925        591        334         14         30        355\n', 
'-/+ buffers/cache:        205        719\n', 
'Swap:           99          0         99\n', 
'Total:        1025        591        434\n']
 So, we need total memory, usage and free memory.
 We should find the index of capital T which is unique at this string
"""
T_ind=mem.index('T')
"""
Than, we can recreate the string with this information. After T we have,
"Total:        " which has 14 characters, so we can start from index of T +14
and last 4 characters are also not necessary.
We can create a new sub-string using this information
"""
mem_G=mem[T_ind+14:-4]
"""
The result will be like
1025        603        422
we need to find first index of the first space, and we can start our substring
from from 0 to this index number, this will give us the string of total memory
"""
S1_ind=mem_G.index(' ')
mem_T=mem_G[0:S1_ind]

print 'Summary = ' + mem_G
print 'Total Memory = ' + mem_T +' MB'

Easily we can get the Used Memory and Free Memory

    """
        Similarly we will create a new sub-string, which will start at the second value. 
        The resulting string will be like
        603        422
        Again, we should find the index of first space and than the 
        take the Used Memory and Free memory.
        """
        mem_G1=mem_G[S1_ind+8:]
        S2_ind=mem_G1.index(' ')
        mem_U=mem_G1[0:S2_ind]

        mem_F=mem_G1[S2_ind+8:]
    print 'Used Memory = ' + mem_U +' MB'
    print 'Free Memory = ' + mem_F +' MB'
1
  • 1
    free is not installed by default on Mac Commented Apr 29, 2020 at 11:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.