Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memoization does not release memory after cache_clear #25

Open
eldernewborn opened this issue Sep 15, 2022 · 1 comment
Open

Memoization does not release memory after cache_clear #25

eldernewborn opened this issue Sep 15, 2022 · 1 comment

Comments

@eldernewborn
Copy link

Looking at the profiler output, it seems like cached decorator is not releasing memory:

    32   2578.6 MiB      0.0 MiB           1       c = MemoizeClass()
    33   2829.4 MiB      0.0 MiB        1001       for i in range(1000):
    34   2829.4 MiB    250.8 MiB        1000           c.get_something(random.randint(0, 4000000000000))
    35   2829.4 MiB      0.0 MiB           1       print(c.get_something.cache_info())
    36   2829.5 MiB      0.1 MiB           1       print(len(list(c.get_something.cache_items())))
    37   2829.5 MiB      0.0 MiB           1       print("############## flushing the cache ################")
    38   2829.5 MiB      0.0 MiB           1       c.get_something.cache_clear()
    39   2829.5 MiB      0.0 MiB           1       print(len(list(c.get_something.cache_items())))
    40   2829.5 MiB      0.0 MiB           1       print(c.get_something.cache_info())
    41   2829.5 MiB      0.0 MiB           1       print(f"found some Garbage:{len(gc.garbage)} items")
    42   2829.5 MiB      0.0 MiB           1       print(f"collected: {gc.collect()}")

environment :
python 3.9.5
memoization: 0.4.0

code to reproduce the results. run with pytest -s for best results.

from memory_profiler import profile
import gc
from memoization import cached
import random
import hashlib


class MemoizeClass:
    def __int__(self):
        self.unique = random.randint(0, 4000000000000)

    @cached(max_size=1362)
    def get_something(self, param):
        return [param] * (2*10**5)
@profile
def test_memoization_cache():
    print("\n")
    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())

    del c
    print(f"found some Garbage:{len(gc.garbage)} items")
    print(f"collected: {gc.collect()}")

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())
    print(len(list(c.get_something.cache_items())))
    print("############## flushing the cache ################")
    c.get_something.cache_clear()
    print(len(list(c.get_something.cache_items())))
    print(c.get_something.cache_info())
    print(f"found some Garbage:{len(gc.garbage)} items")
    print(f"collected: {gc.collect()}")

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())
@eldernewborn
Copy link
Author

Comparing the behavior with functools :

    32   2702.9 MiB      0.0 MiB           1       c = MemoizeClass()
    33   2832.9 MiB -50638.2 MiB        1001       for i in range(1000):
    34   2832.9 MiB -50508.2 MiB        1000           c.get_something(random.randint(0, 4000000000000))
    35   2802.4 MiB    -30.5 MiB           1       print(c.get_something.cache_info())
    36   1661.3 MiB  -1141.1 MiB           1       c.get_something.cache_clear()
    37   1661.3 MiB      0.0 MiB           1       print("############## flushing the cache ################")
    38   1661.3 MiB      0.0 MiB           1       print(c.get_something.cache_info())
    39   1661.3 MiB      0.0 MiB           1       print(f"found some Garbage:{len(gc.garbage)} items")
    40   1661.3 MiB      0.0 MiB           1       print(f"collected: {gc.collect()}")

Same environment
Code:

from memory_profiler import memory_usage,profile
import gc
from functools import lru_cache
import random
import hashlib

class MemoizeClass:
    def __int__(self):
        self.unique = random.randint(0, 4000000000000)

    @lru_cache(maxsize=1362)
    def get_something(self, param):
        return [param] * (2*10**5)

@profile
def test_memoization_cache():
    print("\n")
    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())

    del c
    print(f"found some Garbage:{len(gc.garbage)} items")
    print(f"collected: {gc.collect()}")

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())
    c.get_something.cache_clear()
    print("############## flushing the cache ################")
    print(c.get_something.cache_info())
    print(f"found some Garbage:{len(gc.garbage)} items")
    print(f"collected: {gc.collect()}")

    c = MemoizeClass()
    for i in range(1000):
        c.get_something(random.randint(0, 4000000000000))
    print(c.get_something.cache_info())


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant