Есть ли реализация HashMap на Java, которая не создает мусора?
Мне пришло в голову, что java.util.HashMap
создает мусор для GC при использовании в моей высокопроизводительной системе, которая в основном представляет собой селектор, читающий из сети. Есть ли альтернатива java.util.HashMap
(т.е. Даже не требуется реализовать java.util.Map
, другими словами, он может иметь свой собственный API), который я могу использовать, который не оставит никакого мусора?
GARBAGE = объекты, выходящие за пределы области видимости, и должны быть собраны GC.
Для @durron597:
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
while(true) {
map.put("foo1", "bah1");
map.put("foo2", "bah2");
map.remove("foo1");
Iterator<String> iter = map.keySet().iterator();
while(iter.hasNext()) {
iter.next();
}
}
}
Теперь запустите это с помощью -verbose: gc и посмотрим, что произойдет...:)
Ответы
Ответ 1
Мы также написали набор структур данных, называемых CoralBits, который обеспечивает высокую производительность с нулевым созданием мусора. Он повторно использует итераторы и объекты для размещения карт. Для карт, которые используют примитивы в качестве ключей, мы написали IntMap
и LongMap
. Для карты общего назначения мы написали PooledHashMap
, который реализует java.util.Map
, поэтому вы можете поменять свой код на нулевой мусор.
Trove и Javolution - другие альтернативы, но мы обнаружили, что Javolution создает мусор в некоторых ситуациях.
CoralBits также предоставляет класс инструментальной памяти MemorySampler, который вы можете использовать, чтобы узнать, где в вашем коде создается мусор. В случае a java.util.HashMap
виновник:
java.util.HashMap.createEntry(HashMap.java:901)
Вы можете заглянуть в эту статью, написанную мной, в которой приведен пример использования MemorySampler для обнаружения мусора в ваших приложениях.
Отказ от ответственности: Я один из разработчиков CoralBits.
Ответ 2
Да. Посмотрите, например. в Коллекции Goldman Sachs.
У них есть полная переоценка структуры коллекции JDK (и многое другое) с акцентом на низкий объем памяти. Например, их HashMap
не создает объекты Entry
, пока они действительно не нуждаются. Посмотрите здесь документацию.
Там также Javolution, небольшая библиотека с несколько иной целью - в основном для классов, близких к реальным и прогнозируемым по времени, это также подразумевает низкий уровень мусора.
Если вы хотите сохранить примитивы (что позволяет избежать создания их оберток), посмотрите на один из них:
- Trove - "стандартные" коллекции для примитивов
- Коллекции Goldman Sachs, снова
- HPPC - доступ на более низкий уровень, часто немного быстрее, чем Trove, но позволяет вам легче стрелять в ногу.
- Koloboke - вилка Trove, созданная людьми из OpenHFT. Безумно быстро, быстро развивается. На данный момент (сентябрь 2014 года) поддерживаются только Карты и наборы.
Ответ 3
Вы можете избежать большого количества коллекции мусора, если вы сохраните записи в карте off-heap. Существует несколько библиотек, которые могут вам помочь:
Ответ 4
В библиотеках LibGdx есть массив ArrayMap, который является безмасляной версией hashmap.
http://libgdx.badlogicgames.com/
У них есть несколько других коллекций без мусора.
https://github.com/libgdx/libgdx/tree/master/gdx/src/com/badlogic/gdx/utils
Они отлично работают с небольшим ограничением не допускающей вложенной рекурсии для того же самого итератора.