Вопрос

Я пишу кодек для обработки сообщений, отправленных через TCP, используя протокол провода на заказ. Во время процесса декодирования я создаю ряд Stringс BigDecimalS и даты. Шаблоны доступа клиента-сервера означают, что для клиента часто распространено запрос, а затем декодирует тысячи сообщений ответов, что приводит к большому количеству дублировать Stringс BigDecimalS и т. Д.

Поэтому я создал 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() Чтобы избежать плохого кода, возиться с ним.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top