mkodekar / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

Cache builder with keys using soft references #1845

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Building a map whose keys use soft references was possible until Guava 13 by 
calling MapMaker.softKeys().makeMap():
http://docs.guava-libraries.googlecode.com/git-history/v13.0/javadoc/com/google/
common/collect/MapMaker.html#softKeys()

The resulting map used == to compare keys (by default). Then, using objects 
whose classes override equals() as keys was a bad idea even with weak keys and 
recreating the same (==) key was impossible. Therefore, weakKeys() and 
softKeys() had more or less the same effect except that the behavior of the 
former was more predictable.

However, the objects that I use override both equals and hashCode(), I will 
have to use CacheBuilder.keyEquivalence(Equivalence) (which isn't public) to 
modify the key equivalence and after that, using soft keys will make sense. 
That's why I'd like to reintroduce softKeys() but rather in CacheBuilder.

Please find enclosed my patch. I'll probably have to test it and improve it.

We talked about the limitation that annoyed me and lead me to create this patch 
here:
http://stackoverflow.com/questions/25666925/implementation-of-a-cache-using-soft
-references-both-for-keys-and-values

Original issue reported on code.google.com by goues...@gmail.com on 5 Sep 2014 at 2:07

Attachments:

GoogleCodeExporter commented 9 years ago
It's not clear why softKeys is appropriate for this use case at all.

Generally speaking, using weak or soft references indicates that GC'ing an 
element is a significant event for that key -- which more or less means that it 
has to use reference equality, or else why would it matter?

It sounds like you just want to use softKeys to respond to memory pressure, 
which can cause significantly more trouble than it is worth -- soft references 
can add significant overhead.  I believe we recommend using maximumSize instead 
for these cases.

Original comment by lowas...@google.com on 20 Oct 2014 at 8:20

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 20 Oct 2014 at 8:24

GoogleCodeExporter commented 9 years ago
I use a lot of caches and most of the time, I have no way to compute a 
meaningful value for "maximumSize". Yes I have to respond to memory pressure 
but not too aggressively as some objects are expensive to retrieve. Soft 
references are a good compromise in my case despite the overhead. Actually, I 
only always know a right way of computing a minimal value for "maximumSize" but 
then caching becomes totally inefficient and useless.

For example, imagine that the keys and the values are in a table in a scroll 
pane. I can approximately guess that I won't show more than 100 lines at a 
time, I can set maximumSize to at least 100 but I have no way of computing a 
better (greater but not too big) fixed value based on the memory available for 
the JVM if I have no clue about the memory required for a single line and the 
memory available for the JVM evolves. That's why setting maximumSize is enough 
for more simple cases but not in mine. When a key is unused for a few minutes, 
it is garbage collected only if there is some memory pressure. It helps me to 
keep the applications much more responsive when an end user goes back and 
forth, scrolls up and down.

Original comment by goues...@gmail.com on 21 Oct 2014 at 1:53

GoogleCodeExporter commented 9 years ago
What does softKeys get you in this situation that softValues does not?

Original comment by lowas...@google.com on 21 Oct 2014 at 3:30

GoogleCodeExporter commented 9 years ago
I need both soft keys and soft values because the objects that I store into the 
"soft map" are both heavy, the keys and the values. Using only soft values is 
better than nothing, it's better than using a plain WeakHashMap because the 
values are garbage collected only on memory pressure which is what I want. The 
soft keys allow me to have the same benefit for the keys.

Original comment by goues...@gmail.com on 21 Oct 2014 at 5:49

GoogleCodeExporter commented 9 years ago
IIRC, I'm not actually sure that soft references prioritize GC of bigger 
objects, or anything: they just start getting GC'd in the presence of memory 
pressure at all.  So if you start experiencing GC pressure and you're using 
softValues, then your values will start getting GC'd, and your keys will start 
getting evicted (and made eligible for GC) when cache cleanup occurs.

Original comment by lowas...@google.com on 21 Oct 2014 at 6:47

GoogleCodeExporter commented 9 years ago
I meant that using soft references for both the keys and the values isn't 
stupid in most of my cases because both don't have a negligible memory 
footprint. Do you suggest to use strong keys with soft values?

Original comment by goues...@gmail.com on 21 Oct 2014 at 8:45

GoogleCodeExporter commented 9 years ago
That's exactly what I'm saying, and I'm arguing that that gets you essentially 
the behavior you're looking for.

Original comment by lowas...@google.com on 21 Oct 2014 at 8:47

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<issue id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:08

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:07