millka_15
millka_15

Reputation: 369

How to cache data via Guava Cache using available memory as parameter?

It is possible remove data from cache, when available runtime memory near with overflow? The cache implementetion is below:

Cache<String, Cache<String, List<String>>> cache = CacheBuilder.newBuilder()
            .maximumWeight((int) ((Runtime.getRuntime().totalMemory() / 1024) * 0.9))
            .weigher((Weigher<String, Cache<String, List<String>>>) (key, val) -> runtimeMemory())
            .build();

public static int runtimeMemory() {
        long totalMemory = Runtime.getRuntime().totalMemory() / 1024;
        long freeMemory = Runtime.getRuntime().freeMemory() / 1024;
        return (int) (totalMemory - freeMemory);
    }

It is work or no ? Or weigher summarizes runtimeMemory() for each value?

Upvotes: 0

Views: 587

Answers (2)

Louis Wasserman
Louis Wasserman

Reputation: 198014

There is no good way for Guava's Cache -- or any on-heap cache implementation, honestly -- to do what you ask. Soft references may appear to work, but are much more likely to cause awful behavior -- e.g. your JVM may perform continuous, constant full garbage collections.

The best way to address this issue is really and truly to experiment and find a maximumSize parameter that works for you. Your implementation will not work, either, as it doesn't attempt to weigh one particular entry.

Upvotes: 3

Srđan Miljević
Srđan Miljević

Reputation: 67

If your objective is to avoid running out of memory JVM-wide, then the garbage collector is the right guy for the job. I suggest you use soft-values, like so:

Cache<String, Cache<String, List<String>>> cache = CacheBuilder.newBuilder()
        .softValues()
        .build();

This sets up a cache which wraps any value it stores in a SoftReference. Softly-referenced objects will be garbage-collected in a globally least-recently-used manner in response to memory demand and entry invalidated in the cache.

Upvotes: 0

Related Questions