Используйте Premgen Space или Roll-My-Seire Method Method?
-
30-09-2019 - |
Вопрос
Я пишу кодек для обработки сообщений, отправленных через TCP, используя протокол провода на заказ. Во время процесса декодирования я создаю ряд String
с BigDecimal
S и даты. Шаблоны доступа клиента-сервера означают, что для клиента часто распространено запрос, а затем декодирует тысячи сообщений ответов, что приводит к большому количеству дублировать String
с BigDecimal
S и т. Д.
Поэтому я создал InternPool<T>
Класс, позволяющий мне стажер каждый класс объекта. Внутренне бассейн использует WeakHashMap<T, WeakReference<T>>
. Отказ Например:
InternPool<BigDecimal> pool = new InternPool<BigDecimal>();
...
// Read BigDecimal from in buffer and then intern.
BigDecimal quantity = pool.intern(readBigDecimal(in));
Мой вопрос: я использую InternPool
для BigDecimal
Но я должен учитывать также использовать его для String
вместо String
С. intern()
Метод, который я считаю, использует пространство Premgen? Какое преимущество использования Permgen Space?
Решение
Вероятно, что JVM String.intern()
Бассейн будет быстрее. AFAIK, он реализован в родном коде, так что это должен быть быстрее и используйте меньше места, чем у бассейна, реализованного WeakHashMap
а также WeakReference
. Отказ Вам нужно будет сделать тщательный бенчмаркинг, чтобы подтвердить это.
Однако, если у вас нет огромных чисел долгоживущих дублирующихся объектов, я сомневаюсь, что вмешательство (либо в Permgen, либо с вашими собственными бассейнами) будет иметь большую разницу. И если соотношение уникальных для дублированных объектов слишком низко, то вмешась, что вместо того, чтобы увеличить количество живых объектов (заставляя GC взять дольше) и уменьшить производительность из-за накладных расходов, и так далее. Таким образом, я бы также выступил бы от сравнительного анализа «Стажеров» против «нет стажеров».
Другие советы
Если у вас уже есть такой InternPool
Класс, он думает, что лучше использовать это, чем выбрать другой интеграцию для строк. Особенно с тех пор, как String.intern()
кажется, дает гораздо более сильную гарантию, чем вам на самом деле нужно. Ваша цель состоит в том, чтобы уменьшить использование памяти, поэтому идеальное взаимопонимание для срока службы JVM на самом деле не требуется.
Кроме того, я бы использовал Коллекции Google MapMaker
создать а InternPool
Чтобы избежать повторного создания колеса:
Map<BigDecimal,BigDecimal> bigDecimalPool = new MapMaker()
.weakKeys()
.weakValues()
.expiration(1, TimeUnits.MINUTES)
.makeComputingMap(
new Function<BigDecimal, BigDecimal>() {
public BigDecimal apply(BigDecimal value) {
return value;
}
});
Это даст вам (правильно реализованные) слабые ключи и значения, безопасность потоков, автоматическая очистка старых записей и очень простой интерфейс (простой, известной Map
). Быть уверенным, что вы также можете обернуть его, используя Collections.immutableMap()
Чтобы избежать плохого кода, возиться с ним.