Implementing a Simple Weak Cache for Memory Management
Owner: SnippetBot
Created: 2026-09-14 00:00:36
Size: 2.05 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import weakref
class LargeObject:
def __init__(self, obj_id, data_size):
self.obj_id = obj_id
self.data = bytearray(data_size * 1024 * 1024) # Simulate large data (e.g., 1MB per data_size)
print(f"LargeObject {self.obj_id} created with {data_size}MB data.")
def __repr__(self):
return f"<LargeObject {self.obj_id}>"
def __del__(self):
print(f"LargeObject {self.obj_id} garbage collected.")
# Create a WeakValueDictionary to serve as a cache
# Objects stored here will not prevent garbage collection if no other strong references exist.
weak_cache = weakref.WeakValueDictionary()
def get_or_create_object(obj_id, data_size=1):
if obj_id not in weak_cache:
print(f"Cache miss for {obj_id}. Creating new object...")
obj = LargeObject(obj_id, data_size)
weak_cache[obj_id] = obj # Store a weak reference
return obj
print(f"Cache hit for {obj_id}.")
return weak_cache[obj_id]
# --- Demonstration ---
# Get object 1: it will be created and cached weakly
obj1_ref1 = get_or_create_object('OBJ_1', 2) # Create 2MB object
print(f"Got obj1_ref1: {obj1_ref1}")
# Get object 1 again: it will be fetched from cache
obj1_ref2 = get_or_create_object('OBJ_1')
print(f"Got obj1_ref2: {obj1_ref2}")
# Get object 2: it will be created and cached weakly
obj2_ref1 = get_or_create_object('OBJ_2', 3) # Create 3MB object
print(f"Got obj2_ref1: {obj2_ref1}")
print("
Removing strong references to OBJ_1 and forcing garbage collection...")
# If we delete all strong references to obj1, it will be garbage collected,
# and thus removed from the weak_cache.
del obj1_ref1
del obj1_ref2
import gc # Force garbage collection
gc.collect()
print(f"Cache after GC (should be just OBJ_2 if OBJ_1 was collected): {list(weak_cache.keys())}")
# Try to get OBJ_1 again: it should be recreated because it was collected
obj1_ref3 = get_or_create_object('OBJ_1', 1)
print(f"Got obj1_ref3: {obj1_ref3}")
print("
Final cleanup...")
del obj2_ref1
del obj1_ref3
gc.collect()
print(f"Cache after final cleanup: {list(weak_cache.keys())}")