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.
Asked
Active
Viewed 7.6k times
73
-
You could read `/proc/meminfo`. – Lee Duhem Feb 28 '14 at 18:30
-
`/proc/meminfo` should be available on pretty much all linux installs. – Marc B Feb 28 '14 at 18:30
-
1You don't need `/proc/meminfo` because [`sysconf` has the answer](http://stackoverflow.com/a/28161352/832230). – Asclepius Jan 27 '15 at 20:13
-
/proc is only available when CONFIG_PROC_FS=y . True for desktops, servers, phones, not always true for embedded devices. – rsaxvc Jul 16 '16 at 15:06
-
1You rarely should care about *physical* memory (imagine for example a virtual processor thru docker etc...) – Basile Starynkevitch Aug 27 '17 at 19:33
-
@BasileStarynkevitch Could you expand on that topic in [Why does `/proc/meminfo` show 32GB when AWS instance has only 16GB?](https://stackoverflow.com/q/61498709/562769) – Martin Thoma Apr 29 '20 at 11:45
4 Answers
99
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.

yossiz74
- 889
- 1
- 9
- 16

Corey Goldberg
- 59,062
- 28
- 129
- 143
-
1`mem = virtual_memory()` and then `# total physical memory`? Sounds great – Thomas Weller Aug 30 '18 at 18:44
-
Future proofed with 2018/12/18: https://web.archive.org/web/20181228093919/https://psutil.readthedocs.io/en/latest/#psutil.virtual_memory – Lorem Ipsum Jan 02 '19 at 17:17
-
int(np.round(psutil.virtual_memory().total / (1024. **3))) with a tip from @Asclepius. – user1098761 Feb 01 '23 at 04:37
73
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
andSC_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

Asclepius
- 57,944
- 17
- 167
- 143
-
1@sorin, `os.sysconf('SC_PHYS_PAGES')` apparently doesn't work on OS X. Although the OS X man page for [`sysconf`](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sysconf.3.html) 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](https://apple.stackexchange.com/questions/4286/is-there-a-mac-os-x-terminal-version-of-the-free-command-in-linux-systems). – Asclepius Jul 17 '15 at 18:58
-
2FWIW, the `os.sysconf()` approach also works with Python 3 and even under Solaris 10. – maxschlepzig Aug 27 '17 at 19:25
-
1I am happy to report that it's working on MacOS X 10.13 (High Sierra) with Python 3.6.4. – John Difool Apr 19 '18 at 16:49
-
`/proc/meminfo` seems not to work as expected on AWS: [Why does `/proc/meminfo` show 32GB when AWS instance has only 16GB?](https://stackoverflow.com/q/61498709/562769) – Martin Thoma Apr 29 '20 at 11:15
-
1On 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')` – Nick Korostelev Jun 26 '20 at 18:40
-
1Ideally I would want to figure out how to do this without external dependencies such as `psutil` – Nick Korostelev Jun 27 '20 at 01:09
-
@NickKorostelev Why don't you see how `psutil` does it on the Mac? It's however a waste of time to invest effort figuring this out on the Mac. Or just use a real operating system such as Linux. – Asclepius Jun 27 '20 at 02:32
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])

Corey Goldberg
- 59,062
- 28
- 129
- 143

Seth
- 45,033
- 10
- 85
- 120
-
5
-
I mistook distribution-agnostic for cross-platform... and now I see it's tagged Linux. my bad :) – Corey Goldberg Jun 21 '18 at 00:19
-
`/proc/meminfo` seems not to work as expected on AWS: [Why does `/proc/meminfo` show 32GB when AWS instance has only 16GB?](https://stackoverflow.com/q/61498709/562769) – Martin Thoma Apr 29 '20 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. – ThisGuyCantEven Feb 12 '21 at 15:08
-
Also @martin-thoma What AWS image are you using, I do not have this issue with the latest amazonlinux2. – ThisGuyCantEven Feb 12 '21 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'

CodeGench
- 1,245
- 10
- 8