'EhCache pre-allocates all off-heap memory

When creating an EhCache cache with off-heap memory, the size of off-heap is immediately allocated, while it may never be used. This creates problems when creating multiple caches, or even having multiple cache unit tests.

Is there a way to use EhCache's off-heap memory without pre-allocating all this memory?

As an illustration, the following code will fail at cache creation because of the size of the off-heap memory (see below):

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;

public class EhCacheCache {

    private static final CacheManager CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder()
            .with(CacheManagerBuilder.persistence(".\\quantity-cache"))
            .build(true);

    private final Cache<Integer, Double> cache;

    EhCacheCache() {
        CacheConfigurationBuilder<Integer, Double> cacheCfgBuilder = CacheConfigurationBuilder
                .newCacheConfigurationBuilder(Integer.class, Double.class,
                        ResourcePoolsBuilder.newResourcePoolsBuilder()
                                .heap(1, MemoryUnit.GB)
                                .offheap(100, MemoryUnit.GB));
        this.cache = CACHE_MANAGER.createCache(toString(), cacheCfgBuilder);
    }

    public void put(Integer key, Double value) {
        cache.put(key, value);
    }

    public Double get(Integer key) {
        return cache.get(key);
    }

}

This simple unit test throws an exception at cache creation:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class EhCacheCacheTest {

    private EhCacheCache cache;

    @Before
    public void doBefore() {
        cache = new EhCacheCache();
    }

    @Test
    public void testPutGet() {
        final Double value = 1234D;

        cache.put(1, value);
        final Double valueFromCache = cache.get(1);

        Assert.assertEquals(value, valueFromCache);
    }

}
java.lang.IllegalStateException: Cache 'com.infor.scm.ap.impl.dataset.cache.EhCacheCache@2f8f5f62' creation in EhcacheManager failed.

    at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:302)
    at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:252)
    at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:247)
    ...
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.ehcache.StateTransitionException: Attempting to allocate 100.0GB of memory when the host only contains 31.7GB of physical memory


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source