-
Notifications
You must be signed in to change notification settings - Fork 4
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
Remove keys when values are nullified #2
Comments
I wrote this class to use as a very very simple object cache. The HashMap would keep values in memory as long as said value is hard-referenced anywhere else in the application. Once all references in the application are gone, only a WeakValue<> reference remains in the HashMap and the value is kept in memory as long as the JVM garbage collector keeps it in memory. If I need the same key some time later, I could see if it's still in memory and avoid re-calculating the value. The JVM garbage collector is designed to keep WeakValue<> values in memory unless low-mem pressure requires it to free memory for other use, which is exactly what I wanted for my lazy memory cache. Does this help? |
No, not really. I think I understand your motivation, but I didn't understand how it addresses my issue. The answer might be, "No, sorry, it is not feasible to enhance This was a feature of the weak hash table I was using in SBCL Common Lisp. In that system, there is even a debugging callback, which notifies the application before data is garbage collection. This is helpful for making sure the data is really being cleared out. |
This code is 6yrs old and I have to admit that I can't help you much. There is an internal processQueue() method that is used as a cleanup task to remove those hash entries that the garbage collector has removed from memory by the time you try to access it. Back when I used this code in a small Java project, WeakValueHashMap correctly removed unreferenced values from the HashMap and didn't return null values for them, provided that you use WeakValueHashMap's access methods like get/put/size/values etc. |
Ahh, interesting. I appreciate that it is difficult to remember work done 6 years ago. I don't even remember what I did yesterday sometimes. Just to make sure I understand what you are saying. What do you mean by "removed unreferenced values"? Do you mean that the corresponding key was removed from the map, or only the value was removed. If only the value was removed, and not the key, then how did you prevent null from being returned when you access a key whose value was removed? |
I guess I now understand the issue. Returning null for a non-existing value is the defined behaviour for get() for any implementation of a HashMap:
Thus, if the value has been removed from memory by the time you try to access it, it will always be null if you access it via get(). The entry will not appear though if you check with containsKey() or values(). |
Problem is that if you do something akin to My original use for this code was for an application with no null values stored in that hashmap. Again, this was meant as a very quick hack for a really simple in-memory cache. It served me well, but a proper memory cache would use a more sophisticated cache scheme. |
WeakValueHashMap keeps all values referenced using a WeakReference(). If there is no normal reference left to a value, such a weakly referred value may be cleaned up by the garbage collector. The garbage collector queue will announce its intent to remove an object from memory on its next run, therefore processQueue() removes those hash entries - both key and the weak reference to the value - from WeakValueHashMap. |
Ah, this is interesting. Because from the Scala side, If I access the non-existent value in However, if I understand you correctly you are saying that if keys are remaining in the hash, but now associated with null values, then it is a bug in |
BTW, one thing I didn't mention. I was very happy to find this class implemented. I find it genial that it exists. And don't interpret my questions as complaint. |
I don't know enough about Scala and also, this code is 6yrs old and it's possible that things have changed on the Java side by now, too. It's very well possible that my old code is buggy based on today's Java standards. |
(Or that it was buggy from the start. Ahem.) |
I don't really understand the Java implementation of WeakValueHashMap. I'm using this in a Scala project. The behavior in Scala is that when values become otherwise unreferenced, then the hash map value is nullified, i.e., the object is removed from he value position and is replaced by null. For my application it would be much better if the key/value pair were simply removed from the hash map.
Can I achieve this with this class? I'd be happy if it worked this way automatically, or if there were a Boolean flag on the constructor to specify this behavior, or even if I could register a callback which would be called with the hash map and key as argument whenever a value has been (or is about to be) nullified. That would give me a chance to remove the key myself.
Otherwise, it is not really feasible (in terms of runtime complexity) to search the hash table periodically for null values, and remove the corresponding keys.
I'd appreciate either advise, enhancement, or a clue about how to enhance the code. I'm happy to create a PR, but I'm not a java-ist. I've never written a line of java in my life.
The text was updated successfully, but these errors were encountered: