It's a software architect question closely related with Javascript language abilities. I have C++ background and now I'm trying to architect some middle-sized solution with caching.
Here is some pseudo-code in typescript illustrating the problem:
class CacheHolder {
cacheItems: Map<number, SharedCachedItem>
get(id:number): SharedCachedItem {
let item = cacheItems.get(id);
if(item)
return item;
item = new SharedCachedItem();
// ... here loads item somehow ...
cacheItems.set(id, item);
return item;
}
}
I want SharedCachedItem to be released when it's not used (i.e. not referenced from anywhere except for CacheHolder). CacheHolder.cacheItems holds permanent references to all SharedCachedItem, this prevents Javascript from garbage collecting them, so I'm forced to implement some memory management by hand.
Solution in Java
Easy and straightforward:
Map<number, WeakReference<SharedCachedItem> >
Sadly there is no WeakReference in Javascript. Or am I missing something?
Notice: I know about WeakMap and it seems useless for this, because it only supports "Weak" for Key and not for Value: (new WeakMap()).set(1,{})
throws exception. WeakMap details here
Solution in C++
In C++ memory management is always made 'by hand'. I'd use reference-counting for SharedCachedItem (Boost example) togather with RAII principle to manage this "reference holder" objects.
Sadly RAII is impossible in Javascript. Or am I missing something?
Last resort C++ style solution
Use reference-counting with manual call to .release() when finished using it. This is what I'm going to implement for now. The problem with this solution is that ".release()" can very easily be forgotten, especially for cases with exceptions in try..catch more info why
So, the question:
What is the best way to release unused shared objects in javascript?