Подтвердить что ты не робот

Реальная жизнь, практический пример использования String.intern() в Java?

Я видел много примитивных примеров, описывающих, как работает String intern(), но мне еще предстоит увидеть реальный случай использования, который выиграет от него.

Единственная ситуация, о которой я могу мечтать, - это иметь веб-службу, которая получает большое количество запросов, каждый из которых очень похож по своей природе из-за жесткой схемы. Посредством intern() в именах полей запроса в этом случае потребление памяти может быть значительно уменьшено.

Может ли кто-нибудь предоставить пример использования intern() в производственной среде с большим успехом? Может быть, это пример популярного предложения с открытым исходным кодом?

Изменить: я имею в виду ручной интернационал, а не гарантированное интернирование строковых литералов и т.д.

4b9b3361

Ответ 1

Интернирование может быть очень полезным, если у вас есть строки N, которые могут принимать только K разные значения, где N намного превышает K. Теперь вместо хранения N строк в памяти вы сохраните только K.

Например, у вас может быть тип ID, который состоит из 5 цифр. Таким образом, могут быть только 10^5 разные значения. Предположим, что теперь вы разбираете большой документ с множеством ссылок/перекрестных ссылок на значения ID. Скажем, этот документ содержит 10^9 ссылок total (очевидно, некоторые ссылки повторяются в других частях документов).

So N = 10^9 и K = 10^5 в этом случае. Если вы не интернируете строки, вы будете хранить строки 10^9 в памяти, где много этих строк equals (Принцип Pigeonhole). Если вы intern() строка ID, которую вы получаете при разборе документа, и вы не держите ссылки на строки, которые вы читаете из документа (чтобы они могли быть собраны мусором), вы никогда не будете необходимо сохранить в памяти более чем 10^5 строк.

Ответ 2

Не полный ответ, но дополнительное питание для размышлений (найдено здесь):

Поэтому основным преимуществом в этом случае является то, что использование оператора == для интернализированных строк намного быстрее, чем использование метода equals() [для неинтерминированных строк]. Итак, используйте метод intern(), если вы собираетесь сравнивать строки больше, чем время или три.

Ответ 3

У нас была производственная система, которая обрабатывает буквально миллионы частей данных за раз, многие из которых имеют строковые поля. Мы должны были интернировать струны, но была ошибка, которая означала, что мы не были. Исправив ошибку, мы избегали делать очень дорогостоящие (минимум 6 цифр, возможно, 7) обновление сервера.

Ответ 4

Примеры, в которых интернирование будет полезным, включают строки с большими номерами, где:

  • строки, вероятно, выживут несколько циклов GC и
  • вероятно, будет несколько копий большого процента строк.

Типичные примеры включают разделение/разбор текста на символы (слова, идентификаторы, URI), а затем прикрепление этих символов к долговечным структурам данных. Обработка XML, компиляция языка программирования и тройные хранилища RDF/OWL spring, чтобы рассматривать как приложения, где интернирование, вероятно, будет полезным.

Но интернирование не лишено проблем, особенно если окажется, что приведенные выше предположения неверны:

  • структура данных пула, используемая для хранения интернированных строк, занимает дополнительное пространство,
  • интернирование занимает время и
  • интернирование не предотвращает создание дублирующей строки в первую очередь.

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

Ответ 5

Никогда, когда-либо, используйте intern из предоставленных пользователем данных, поскольку это может привести к атакам отказа в обслуживании (поскольку строки intern() ed никогда не освобождаются). Вы можете выполнить проверку в строках, предоставленных пользователем, но затем вы выполнили большую часть работы, необходимой для intern().