I am using the Ignite metrics API to monitor memory usage levels in an
attempt to avoid OOM conditions.

I have found that the metrics API appears to provide reasonably accurate
figures as entries are being written to the cache - but usage levels do not
come down again when entries are removed. I have tried removing all entries,
individual entries and even destroying the cache. I have also tried waiting
for a significant period of time.

Even when the cache is destroyed, the memory usage figure does not appear to
drop. In fact, removing entries can even cause an increase in the figure.
Despite the metrics, it is possible to insert new entries following removal
of the old ones - indicating that space is in fact available.

A reproducer is below and produces results like:

Out of memory: CachePartialUpdateException after 89MB
Memory used: 99.39624%
Memory used: 99.41027%
Memory used: 99.41406%



package mytest;

import org.apache.ignite.DataRegionMetrics;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.failure.NoOpFailureHandler;
import org.junit.Test;

import javax.cache.CacheException;

public class MemoryTest {

    private static final String CACHE_NAME = "cache";
    private static final String DEFAULT_MEMORY_REGION = "Default_Region";
    private static final long MEM_SIZE = 100L * 1024 * 1024;


    @Test
    public void testOOM() throws InterruptedException {
        try (Ignite ignite = startIgnite("IgniteMemoryMonitorTest1")) {
            fillDataRegion(ignite);
            IgniteCache<Object, Object> cache =
                    ignite.getOrCreateCache(CACHE_NAME);

            // Clear all entries from the cache to free up memory 
            memUsed(ignite);
            cache.clear();      // Fails here
            cache.put("Key", "Value");
            memUsed(ignite);

            cache.destroy();
            Thread.sleep(5000);
            memUsed(ignite);
        }
    }


    private Ignite startIgnite(String instanceName) {
        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setIgniteInstanceName(instanceName);
        cfg.setDataStorageConfiguration(createDataStorageConfiguration());
        cfg.setFailureHandler(new NoOpFailureHandler());
        return Ignition.start(cfg);
    }

    private DataStorageConfiguration createDataStorageConfiguration() {
        return new DataStorageConfiguration()
                .setDefaultDataRegionConfiguration(
                        new DataRegionConfiguration()
                                .setName(DEFAULT_MEMORY_REGION)
                                .setInitialSize(MEM_SIZE)
                                .setMaxSize(MEM_SIZE)
                                .setMetricsEnabled(true));
    }


    private void fillDataRegion(Ignite ignite) {
        byte[] megabyte = new byte[1024 * 1024];

        int storedDataMB = 0;
        try {
            IgniteCache<Object, Object> cache =
                    ignite.getOrCreateCache(CACHE_NAME);
            for (int i = 0; i < 200; i++) {
                cache.put(i, megabyte);
                storedDataMB++;

                memUsed(ignite);
            }
        } catch (CacheException e) {
            System.out.println("Out of memory: " +
e.getClass().getSimpleName() + " after " + storedDataMB + "MB");
        }
    }

    private void memUsed(Ignite ignite) {
        DataRegionConfiguration defaultDataRegionCfg =
ignite.configuration()
                .getDataStorageConfiguration()
                .getDefaultDataRegionConfiguration();
        String regionName = defaultDataRegionCfg.getName();
        DataRegionMetrics metrics = ignite.dataRegionMetrics(regionName);
        float usedMem = metrics.getPagesFillFactor() *
metrics.getTotalAllocatedPages() * metrics.getPageSize();
        float pctUsed = 100 * usedMem / defaultDataRegionCfg.getMaxSize();
        System.out.println("Memory used: " + pctUsed + "%");
    }
} 



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Reply via email to