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"" 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())}")