com.sleepycat.je.evictor.Evictor
The Evictor is responsible for maintaining the JE cache. Since object sizes are not directly manipulated in a Java application, the cache is actually a collection of in-memory btree nodes, implemented by com.sleepycat.je.dbi.INList. Nodes are selected from the INList for removal, which is done by detaching them from the in-memory tree, and by removing them from the INList. Once all references to them are removed, they can be GC'd by the JVM. There are three main components. Arbiter: queries the memory budget to decide whether eviction is needed TargetSelector : chooses a target node Evictor: does the work of detaching the node. The TargetSelector and Evictor classes are subclassed to provide private/shared cache implementations. A shared cache is used by multiple environments within a single JVM, and is seen logically as a single INList collection, although it is implemented by an umbrella over multiple INLists. The Evictor owns a thread pool which is available to handle eviction tasks. Eviction is carried out by three types of threads: 1. The application thread, in the course of doing critical eviction 2. Daemon threads, such as the cleaner or INCompressor, in the course of doing their respective duties 3. Eviction pool threads We prefer that the eviction pool threads do as much of the eviction as possible, and that the application threads do as little, because eviction adds latency to the perceived application response time. To date, it has been impossible to completely remove eviction responsiblities from the application threads, because the process doesn't have sufficient feedback, and can incur an OutOfMemoryException. The eviction pool is a standard java.util.concurrent thread pool, and can be mutably configured in terms of core threads, max threads, and keepalive times. Since three types of threads can concurrently do eviction, it's important that eviction is both thread safe and as parallel as possible. Memory thresholds are generally accounted for in an unsynchronized fashion, and are seen as advisory. The only point of true synchronization is around the selection of a node for eviction. The act of eviction itself can be done concurrently. The eviction method is not reentrant, and a simple concurrent hash map of threads is used to prevent recursive calls.