LinkedHashMap内存泄漏在JDK 7中

时间:2016-08-15 03:08:35

标签: java caching memory-leaks java-7 linkedhashmap

我使用LinkedHashMap编写了一个LRU缓存。我用它来缓存一些内存表。表大小从几行到几千行不等。为了更精确地控制内存,我设置了最大缓存行而不是最大表。缓存在多线程上下文中运行。我在JDK7和JDK8中测试代码。他们有完全不同的结果。在JDK7中,似乎内存泄漏非常快。在JDK8中,它运行非常稳定,没有内存泄漏。有人可以帮忙吗?我无法相信JDK 7有如此严重的错误!

以下是代码:

public class TableLRUCache<K>
{
    private String cacheName;
    private TableLRUCache.InternalMap container;

    public TableLRUCache(String cacheName, int cacheSize)
    {
        this.cacheName = cacheName;
        container = new TableLRUCache.InternalMap(cacheSize);
    }

    public synchronized TableWrapper get(K k)
    {
        TableWrapper result = (TableWrapper) container.get(k);
        if (result != null)
        {
            result.hit();
        }
        return result;
    }

    public synchronized TableWrapper put(K k, TableWrapper tableWrapper)
    {
        TableWrapper result = container.put(k, tableWrapper);
        Iterator<Map.Entry<K, TableWrapper>> it = container.entrySet().iterator();
        while (it.hasNext())
        {
            if (container.totalRows <= container.maxRows)
            {
                break;
            }
            Map.Entry<K, TableWrapper> entry = it.next();
            if (!entry.getValue().isPersist())
            {
                //the table has not persistent, delete it later.
                continue;
            }
            it.remove();
            updateTableSurviveStatistic(entry.getValue());
            BaseTable deleteTable = entry.getValue().table;
            if (deleteTable != null)
            {
                container.totalRows -= deleteTable.getRows().size();
            }
        }
        return result;
    }

    public synchronized TableWrapper remove(K k)
    {
        TableWrapper result = container.remove(k);
        if (result != null)
        {
            updateTableSurviveStatistic(result);
        }
        return result;
    }

    private void updateTableSurviveStatistic(TableWrapper tableWrapper)
    {
        //update statistic
    }

    public synchronized String statistic()
    {
        // get statistic
        return null;
    }

    public synchronized int getCacheSize()
    {
        return container.maxRows;
    }

    public synchronized int getUsedRows()
    {
        return container.totalRows;
    }

    public class InternalMap<K> extends LinkedHashMap<K, TableWrapper>
    {
        private int maxRows;
        private int totalRows = 0;

        public InternalMap(int cacheSize)
        {
            super(16, (float) 0.75, true);
            this.maxRows = cacheSize;
        }

        @Override
        public TableWrapper put(K key, TableWrapper tableWrapper)
        {
            TableWrapper old = this.remove(key);
            if (old != null)
            {
                totalRows -= old.table.getRows().size();
            }
            if (tableWrapper != null)
            {
                totalRows += tableWrapper.table.getRows().size();
            }
            return super.put(key, tableWrapper);
        }

        @Override
        public TableWrapper remove(Object key)
        {
            TableWrapper result = super.remove(key);
            if (result != null)
            {
                totalRows -= result.table.getRows().size();
            }
            return result;
        }
    }
}

0 个答案:

没有答案