0

So, I have a dictionary which I want to flush out once a day

So.. something like

d = {}

def refresh():
    global d
    now = datetime.datetime.now()
    if now >= TIME_TO_REFRESH:
       d  = {}

When I look into the memory profile, the memory grows as the size of d grows, but then when its time to refresh, I expect the memory to drop. The issue is that it does.. but not to a great extent. I am wondering if there is something else I need to do in order to make sure that the entire contents of the dictionary get flushed. Maybe its already happening but I am not able to find a good resource to see how the garbage collector works in this instance?

frazman
  • 32,081
  • 75
  • 184
  • 269

2 Answers2

2

In example above you are not really resetting that dictionary. You just assign new empty one to the existing name. To reset it you would need to call d.clear(). Even setting it to None will be just change in binding, not in the mutable object itself.

Python interpreter decides when to free memory using reference counting, which means that it counts how many references (names that point to actual memory structure) exists. If it drops to zero, memory is not used and can be freed. So if some other part of your program holds reference memory can't be freed. This is very simplified statement (see article I link below for further explanation).

Also component called garbage collector which executes the policy above might decide to delay freeing-up memory for various reasons. You can (but should not need to) force it by executing following code:

import gc
gc.collect()

You can find more on how garbage collection in Python works in this great article: https://rushter.com/blog/python-garbage-collector/

blami
  • 6,588
  • 2
  • 23
  • 31
  • You also don't need to have the `global` statement in this case, too, because you're not assigning to `d`. – B. Morris Sep 15 '19 at 05:03
1

I would consider doing d.clear(). Reassigning creates a new dictionary and the old one will eventually be garbage collected but that is only once all other references to it are gone. .clear() will actually delete what is in the dictionary. https://stackoverflow.com/a/369925/3990806

Adam
  • 3,992
  • 2
  • 19
  • 39
  • I don't think that would affect it given there could still be references to it. That being said I'm not entirely sure how it being a `global` affects all this. I don't think I've ever written a global variable. I think it more matters if you did something like `a = {}, b = a, a = {}`. In this case `b` would still be looking at the original object and thus wouldn't get garbage collected. I'm not sure how this would work if it's a global. I'd imagine once you reassign it all other global references would be looking at the new object. – Adam Sep 15 '19 at 03:22
  • Also wanted to follow up with another thought. You could try doing `from sys import getrefcount` then after you reassign do `print(getrefcount(d))` to check if there are still references to the object. – Adam Sep 22 '19 at 01:24