11# Memory-sensitive Cache
2+ [ ![ Maven Central] ( https://maven-badges.herokuapp.com/maven-central/net.lbruun.cache/memorysensitive-cache/badge.svg )] ( https://maven-badges.herokuapp.com/maven-central/net.lbruun.cache/memorysensitive-cache )
3+ [ ![ javadoc] ( https://javadoc.io/badge2/net.lbruun.cache/memorysensitive-cache/javadoc.svg )] ( https://javadoc.io/doc/net.lbruun.cache/memorysensitive-cache )
24
35A simple in-memory concurrent cache which grows with the available memory and starts evicting
46entries when the JVM is under memory pressure. Thus, the cache shrinks when the memory is needed
@@ -8,17 +10,17 @@ elsewhere in the application. Unused memory is wasted memory. You might as well
810
911- Fully concurrent
1012- Evicts entries when the system is under memory pressure (see [ Eviction] ( #eviction ) below)
11- - Optionally retains hard references to the most recently used X entries (see [ Hard references] ( #hard-references ) below)
13+ - Optionally retains hard references to the most recently used N entries (see [ Hard references] ( #hard-references ) below)
1214
13- ### Eviction
15+ ### Eviction when memory pressure
1416
1517The cache uses ` SoftReference ` to hold the values. This means that the values are eligible for
1618garbage collection when the JVM is under memory pressure. The cache will grow until the point
1719where the JVM needs to reclaim memory, at which point the garbage collector will start
1820collecting the soft references and thus evicting entries from the cache.
1921
20- The JVM's garbage collector does not guarantee a fully predictable collection order of
21- ` SoftReference ` s, but it is biased towards first-in-first-out. This means that the oldest entries
22+ The JVM's garbage collector does not guarantee a fully predictable _ collection order _ of the
23+ ` SoftReference ` s, but it is biased towards first-in-first-out (FIFO) . This means that the oldest entries
2224are more likely to be evicted first from this cache.
2325
2426Also, note that because garbage collection happens
@@ -46,49 +48,42 @@ recently used ones which means the sub-set of hard referenced values changes ove
4648are accessed or added to the cache.
4749
4850
49- ### Background reaper thread
51+ ## Usage
5052
51- The cache has a background thread which periodically clears entries from the cache which
52- have been garbage collected. This is done to prevent the cache from growing indefinitely.
53- Garbage collected values take up the memory occupied by a Key and an empty object reference.
54- For most caches, this is a very small memory footprint, because the objects used for keys tend to be small.
55- Yet, it would still be a waste of memory to keep them around forever. This is the problem solved by
56- the reaper thread.
53+ This cache is suitable where the requirement is that the cache should be able to expand with
54+ the available memory and where it is acceptable that eviction is not fully predictable, but
55+ at least _ biased_ towards first-in-first-out.
5756
58- As can be seen, because of the rather small memory consumption of these empty entries, the
59- reaper thread does not need to run <i >very</i > often. The default is once every 2 minutes,
60- but this can be configured in the constructor. The reaper thread is a daemon thread, so it
61- will not prevent the JVM from shutting down. Nevertheless, it is recommended to call the ` close() `
62- method when the cache is no longer needed, to stop the reaper thread. If not, the reaper thread
63- will continue to run periodically until the JVM shuts down.
57+ ### Requirements
58+ Java 17 or later.
6459
6560
66- ### Performance
61+ ### Maven Central coordinates
6762
68- The performance characteristics of this cache is similar to that of a ` ConcurrentHashMap ` .
63+ ** groupId** : ` net.lbruun.cache ` \
64+ ** artifactId** : ` memorysensitive-cache ` \
65+ ** version** : check [ Maven Central] ( https://search.maven.org/artifact/net.lbruun.cache/memorysensitive-cache )
6966
70- ## Usage
7167
72- This cache is suitable where the requirement is that the cache should be able to expand with
73- the available memory and where it is acceptable that eviction is not fully predictable, but
74- at least _ biased_ towards first-in-first-out.
7568
76- You should close the cache when it is no longer needed by calling the ` close() ` method. If not,
77- the background thread will continue to run.
69+ ### Instantiate the cache
7870
71+ Here is a Spring example of how to instantiate the cache as a Spring bean:
7972
8073``` java
81-
8274import net.lbruun.cache.MemorySensitiveCache ;
8375
8476@Configuration
85- public class MyBean {
77+ public class MyConfig {
8678
87- // Spring will automatically call the close() method on this bean when the application context is closed.
79+ // Spring will automatically call the close() method on this bean
80+ // when the application context is closed.
8881 @Bean
8982 public MemorySensitiveCacheCache <Integer , String > cacheOfAllGoodThings () {
90- // Create a cache which retains hard references to the 10 most recently used entries
91- return new MemoryPressureCache<> (Integer . class, 10 );
83+ // Create a cache which retains hard references to the 100 most recently used entries
84+ return new MemoryPressureCache<> (Integer . class, 100 );
9285 }
9386}
94- ```
87+ ```
88+
89+ You should close the cache when it is no longer needed by calling the ` close() ` method.
0 commit comments