- Most likely, this is because there is an inaccuracy in your code.
Here's an example of a fully working (python 2.7) that has the same problem (I updated the source code a bit for simplicity)
from hurry.filesize import size from pysize import get_size import os import psutil def make_a_call(): return range(1000000) def load_objects(): process = psutil.Process(os.getpid()) print "start method" process = psutil.Process(os.getpid()) print"process consumes ", size(process.memory_info().rss) objects = make_a_call()
Here's the conclusion:
process consumes 7M start method process consumes 7M total size of objects is 30M process consumes 124M exit method process consumes 124M
Difference ~ 100 Mb
And here is the corrected version of the code:
from hurry.filesize import size from pysize import get_size import os import psutil def make_a_call(): return range(1000000) def load_objects(): process = psutil.Process(os.getpid()) print "start method" process = psutil.Process(os.getpid()) print"process consumes ", size(process.memory_info().rss) objects = make_a_call() print "process consumes ", size(process.memory_info().rss) print "total size of objects is ", size(get_size(objects)) print "exit method" def main(): process = psutil.Process(os.getpid()) print "process consumes " + size(process.memory_info().rss) load_objects() print "process consumes " + size(process.memory_info().rss) main()
And here is the updated output:
process consumes 7M start method process consumes 7M process consumes 38M total size of objects is 30M exit method process consumes 124M
Did you notice the difference? You measure the size of objects before measuring the final size of the process, and this leads to additional memory consumption. Let's see why this can happen - here are the sources https://github.com/bosswissam/pysize/blob/master/pysize.py :
import sys import inspect def get_size(obj, seen=None): """Recursively finds size of objects in bytes""" size = sys.getsizeof(obj) if seen is None: seen = set() obj_id = id(obj) if obj_id in seen: return 0
Much is going on here! Most noteworthy is that it contains all the objects that he saw in the set for resolving circular links. If you delete this line, in each case there will not be so much memory.
- First of all, this behavior is highly dependent on whether you are using CPython or something else. As for CPython, this can happen because it is not always possible to immediately return memory to the OS.
Here's a good article on this topic, citing:
If you create a large object and delete it again, Python probably released the memory, but the memory allocators involved do not have to return the memory to the operating system to make it look like the Python process uses much more virtual memory than it actually uses.