Поведение сборки "мусора" для String.intern ()

Если я буду использовать String.intern () для улучшения производительности, как я могу использовать "==" для сравнения интернированной строки, я столкнусь с проблемами сборки "мусора"? Как делает механизм сборки "мусора" интернированных строк, отличаются от нормальных строк?

23
задан Koray Tugay 31 March 2017 в 15:47
поделиться

3 ответа

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

Однако это станет проблемой сборщика мусора, когда ваша строка больше не будет использоваться в приложении, поскольку пул интернированных строк является статическим членом класса String и никогда не будет собираться сборщиком мусора.

Как правило, я считаю, что предпочтительнее никогда не использовать этот внутренний метод и позволить компилятору использовать его только для констант Строки, объявленные следующим образом:

String myString = "a constant that will be interned";

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

Кроме того, String.equals в основе своей вызывает == как оптимизацию, гарантируя, что оптимизация интернированных строк используется под капотом. Это еще одно доказательство == , которое никогда не следует использовать в строках.

11
ответ дан 29 November 2019 в 02:11
поделиться

String.intern () управляет внутренним, встроенным пулом, который имеет некоторые специальные функции, связанные с сборщиком мусора. Это старый код, но если бы он был реализован заново, он использовал бы java.util.WeakHashMap . Слабые ссылки - это способ сохранить указатель на объект, не препятствуя его сбору. Как раз то, что нужно для объединяющего пула, такого как интернированные струны.

То, что интернированные строки являются сборщиком мусора, можно продемонстрировать с помощью следующего кода Java:

public class InternedStringsAreCollected {

    public static void main(String[] args)
    {
        for (int i = 0; i < 30; i ++) {
            foo();  
            System.gc();
        }   
    }

    private static void foo()
    {
        char[] tc = new char[10];
        for (int i = 0; i < tc.length; i ++)
            tc[i] = (char)(i * 136757);
        String s = new String(tc).intern();
        System.out.println(System.identityHashCode(s));
    }
}

Этот код создает 30 раз одну и ту же строку, каждый раз интернируя ее. Кроме того, он использует System.identityHashCode () , чтобы показать, какой хэш-код Object.hashCode () вернул бы в этой интернированной строке. При запуске этот код выводит различные целочисленные значения, что означает, что вы не получаете каждый раз один и тот же экземпляр.

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

21
ответ дан 29 November 2019 в 02:11
поделиться

Прочтите: http://satukubik.com/2009/01/06/java- советы-оптимизация-память-для-строки /

Из вашей информации я могу сделать следующий вывод: Вы интернировали слишком много строк . Если вам действительно нужно интернировать так много String для оптимизации производительности, увеличьте перманентную память , но на вашем месте я сначала проверю , действительно ли мне нужно так много интернированных String.

0
ответ дан 29 November 2019 в 02:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: