2013-09-04 4 views
2

У меня есть консольное Java-приложение, которое нуждается в некоторых данных из базы данных. Поскольку приложение работает постоянно, каждые 30 секунд, чтобы снизить нагрузку на БД, я использую какой-то кеш для данных.Java hashmaps и утечки памяти

Поскольку в базе данных нет большого количества необходимых данных, я использую singleton Hashmap в качестве кеша. Мой класс кэша выглядит следующим образом:

public class Cache extends Hashmap<Integer, Hashmap<Integer, ArrayList<String>> { 
//some code 
} 

Каждой система 5 минут обновит кеш:

1), призывающий «ясно()» для существующих данных 2) заполнение кэша новых данных дБ.

Скажите, если я назову «clear()» для структуры, у меня есть («вложенные» хэш-карты), будет ли явная очистка всех данных в моих ключах кеша, или у меня закончится утечка памяти?

+0

Короткий ответ: Да clear() работает отлично. Длинный ответ (и это похоже на дубликат): http://stackoverflow.com/questions/16231387/good-way-to-clear-nested-maps-in-java – tea2code

+0

Он освобождает объекты key/value на карте, но поддерживает вспомогательный массив/таблицу. –

+0

Звучит как утечка памяти. Обеспечили ли вы, чтобы все соответствующие объекты, связанные с db, не ссылались на элементы в ваших хэшмапах? ...например. 'ResultSet' и т. Д. – vikingsteve

ответ

1

Вы можете сделать это, но я предлагаю лучше заменить его. Это будет более эффективно, если у вас несколько потоков.

public class Cache { 
    private Map<Integer, Map<Integer, List<String>>> map; 

    public Cache(args) { 
    } 

    public synchronized Map<Integer, Map<Integer, List<String>>> getMap() { 
      return map; 
    } 

    // called by a thread every 30 seconds. 
    public void updateCache() { 
      Map<Integer, Map<Integer, List<String>>> newMap = ... 
      // build new map, can take seconds. 

      // quickly swap in the new map. 
      synchronzied(this) { 
       map = newMap; 
      } 
    } 
} 

Это как безопасный поток, так и минимальный удар.

+0

Создана ли карта при создании новой карты' ConcurrentHashMap'? Похоже, что это должно быть, чтобы сохранить этот поток в безопасности. – cyon

+0

Вам нужна только ConcurrentMap, если вы читаете и пишете. В этом случае это только запись и после синхронизированного блока, только чтение. Больше не требуется защита от блокировки/резьбы. –

+0

А я вижу, что вы только пишете на карту, когда вы ее создаете из базы данных, а затем оберните ее, возможно, в 'unmodifiableMap'. Однако вы не подвергаете себя проблеме утечки памяти? Если пользователи присваивают ссылку, возвращаемую 'getMap()' некоторой переменной, то она не получит GCed после 'updateCache'. – cyon

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