2016-09-07 2 views
1

Я пытаюсь исправить проблему утечки памяти. Анализ дампа кучи показывает, что ConcurrentHashMap занимает около 98% of heap memory. Проверяли код, и получается, что создание экземпляра ConcurrentHashMap использует конструктор без параметров. Конфигурация по умолчанию для concurrencyLevel равна 16. После этого создания карты я вижу синхронизированный вызов метода, где данные помещаются на карту.Уровень параллелизма для ConcurrentHashMap в синхронизированном методе

Я хотел бы знать, что, поскольку данные помещаются только в синхронизированном методе, безопасно ли устанавливать параметр concurrencyLevel ConcurrentHashMap в 1?

Ниже приводится пример фрагмент кода:

private volatile Map<String, Integer> storeCache; 

public void someMethod() { 
    storeCache = new ConcurrentHashMap<String, Integer>(); 
    syncMethod(); 
} 

private synchronized void syncMethod() { 
    storeCache.put("Test", 1); 
} 
+0

CHM не использует никаких байтовых массивов, поэтому это не будет иметь никакого значения. Экземпляр CHM по умолчанию использует по меньшей мере на 5 порядков меньше пространства, чем 100 миллионов байтов, используемых байтом. –

+0

Моя точка: CHM не занимает 98% пространства с его внутренностями, но с материалом, который он содержит. Вы не получите ничего, используя параллелизм 1. –

+0

Вам нужно искать утечку памяти в коде приложения. Кто-то добавляет слишком много материала на карту - просто. Вы всегда можете попробовать распечатать карту в текстовом файле. – rghome

ответ

4

Я хотел бы знать, что, поскольку данные кладутся только в синхронном методе, безопасно установить concurrencyLevel из ConcurrentHashMap 1?

Это, безусловно, безопасно в том смысле, что оно не приведет к повреждению карты. Тем не менее, это не будет исправлять утечку памяти. Фактически, вы, вероятно, не хотите синхронизировать доступ к ConcurrentHashMap, который уже гарантирует безопасное чтение и запись из нескольких потоков. Синхронизация извне приведет к однопоточному доступу к вашему CHM, что позволит устранить многие преимущества CHM над HashMap. Если вы удалите и specify a concurrencyLevel equal to the estimated number of concurrent writes, вы, вероятно, достигнете гораздо лучшей производительности.

Что касается утечки памяти, ключи и значения в CHM являются сильными ссылками, то есть сборщик мусора Java не будет их собирать, даже если они больше не ссылаются нигде в вашем коде. Поэтому, если вы используете CHM в качестве кеша для временных значений, вам понадобится .remove(), если ваше приложение больше не нуждается в них.

(Если вы хотите семантику ConcurrentMap без сильных ключей, вы не можете получить, что вне коробки, но Guava provides a pretty good alternative.)

Вы также можете проверить, что ключи, вы находитесь на карте .equals() и .hashCode().

+0

Это имеет смысл. Спасибо Джейсону за подробный ответ. –

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