2013-10-28 5 views
3

Я пытаюсь использовать LinkedHashMap в качестве локального решения кэш-буфер FIFO перезапись его метод removeEldestEntry сохранить фиксированный размер:Фиксированный размер утечки памяти LinkedHashMap?

Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, .75F, false) { 
    protected boolean removeEldestEntry(Map.Entry eldest) { 
     return size() > MAX_CACHE_SIZE; 
    } 
}; 

, но когда я постоянно добавлять новые записи в процессе мониторинга памяти карты я вижу, он продолжает расти до максимальная память виртуальной машины используется, хотя размер карты не увеличивается.

Это по дизайну? Зачем нужно больше памяти, если старые значения будут отброшены, а размер карты ограничен?

UPDATE: по запросу Я прилагаю полный код:

@Test 
public void mapMemory() { 
    final int MAX_CACHE_SIZE = (int) 1E3; 
    Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, 1F, false) { 
     protected boolean removeEldestEntry(Map.Entry eldest) { 
      return size() > MAX_CACHE_SIZE; 
     } 
    }; 

    for (long i = 0; i < 1E10; i++) { 
     lhm.put("key_" + i, "VALUE"); 
    } 
} 
+0

Почему бы не использовать фактическую структуру данных FIFO вместо того, чтобы пытаться подражать друг с HashMap? – GordonM

+0

Мне нужно, чтобы он мог получить значение с помощью ключа. Для чего нужны решения FIFO? – wziska

ответ

0

Второй параметр в конструкторе определяет loadFactor, умноженной на ваш 1-й параметр (размер карты) это дает значение (размер), что вызывает изменение размера карты. Так что в вашем случае вы должны (возможно) использовать loadFactor = 1.

EDIT:
Ваша утечка памяти вызвана чем-то, что вы не показывают нам, что ваш код, как описано выше никогда не приведет к утечке памяти.
Проверьте, где вы можете хранить ссылки на старые значения/объекты. Карта сама по себе НЕ приведет к утечке памяти - если бы все системы, использующие карты (и их было много), сбой каждые несколько часов.

+0

Не работает. Как я описал в вопросе, размер карты не увеличивается. Но использование памяти делает. – wziska

+0

При изменении размера карты она увеличивает емкость, а не ее размер. Значение является точкой запуска при изменении размера карты. При изменении размера карта резервирует MORE MEMORY, чтобы иметь возможность использовать ее позже. Коэффициент приращения по умолчанию равен 2, поэтому использование памяти (почти) удваивается. –

+1

BTW: что «не работает» и каким образом? Если ваш телевизор «не работает», то я не смогу вам помочь - слишком далеко –

0

Если вам нужен случайный доступ к содержимому коллекции, то это не FIFO.

Следует отметить, что коллекции не хранят объекты, но хранят ссылки на объекты, которые являются важным отличием. Хранить тот же объект в двух разных коллекциях не будет иметь значительных издержек памяти, поэтому, возможно, ваше лучшее решение для хранения одного и того же объекта как в очереди, так и в карте, используйте очередь, когда вам нужно поведение FIFO и карта, когда вам нужен произвольный доступ ,

Вы должны помнить, что нужно удалить объект из обеих коллекций, когда вы закончите с ним, хотя в противном случае он не будет GC'd.

+0

Хорошо, я могу думать о написании своей собственной реализации с использованием обеих структур. Но действительно ли это нужно, если уже есть решение, которое я поставил под вопрос? Я только хотел узнать, о чем я должен беспокоиться, если это обширное использование памяти. – wziska

+0

Наличие класса, который обрабатывает все это для вас, будет больше соответствовать хорошему ОО, поскольку вы можете повторно использовать его в других проектах. – GordonM

 Смежные вопросы

  • Нет связанных вопросов^_^