Включена ли функция дедупликации строк сборщика мусора G1 по умолчанию?

JEP 192: Дедупликация строк в G1, реализованная в Java 8 Обновление 20 добавило новую функцию дедупликации String:

Уменьшите данные Live-данных кучи Java, увеличив сборщик мусора G1, чтобы дублировать экземпляры String автоматически и непрерывно дедуплицировались.

На странице JEP упоминается, что параметр командной строки UseStringDeduplication (bool) позволяет включить или отключить функцию дефрагментации. Но страница JEP не заходит так далеко, чтобы указать значение по умолчанию.

➠ Включена или выключена функция деблокирования в сборщике мусора G1 в комплекте с Java 8 и Java 9?

➠ Есть ли метод "getter" для проверки текущего параметра во время выполнения?

Я не знаю, где искать документацию за страницей JEP.

По крайней мере HotSpot -определенные реализации Java 9, Сборщик мусора G1 включен по умолчанию. Этот факт подсказывает этот вопрос сейчас. Для получения дополнительной информации о интернирования и дедупликации String см. эту презентацию 2014-10 Алексея Шипилева в 29:00.

Ответ 1

Дедупликация строк по умолчанию

Для версий Java 8 и Java 9, представленных ниже, UseStringDeduplication по умолчанию false (отключено).

Один из способов проверить настройку функции: отобразить все окончательные флаги для JVM, а затем искать его.

построить 1.8.0_131-b11

    $ java -XX:+UseG1GC  -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version | grep -i 'duplicat'
     bool PrintStringDeduplicationStatistics        = false                               {product}
    uintx StringDeduplicationAgeThreshold           = 3                                   {product}
     bool StringDeduplicationRehashALot             = false                               {diagnostic}
     bool StringDeduplicationResizeALot             = false                               {diagnostic}
     bool UseStringDeduplication                    = false                               {product}
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

построить 9 + 18

    $ java -XX:+UseG1GC  -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version | grep -i 'duplicat'
    uintx StringDeduplicationAgeThreshold          = 3                                        {product} {default}
     bool StringDeduplicationRehashALot            = false                                 {diagnostic} {default}
     bool StringDeduplicationResizeALot            = false                                 {diagnostic} {default}
     bool UseStringDeduplication                   = false                                    {product} {default}
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

Другой способ проверить это с помощью

package jvm;

import java.util.ArrayList;
import java.util.List;

public class StringDeDuplicationTester {

    public static void main(String[] args) throws Exception {
        List<String> strings = new ArrayList<>();
        while (true) {
            for (int i = 0; i < 100_00; i++) {
                strings.add(new String("String " + i));
            }
            Thread.sleep(100);
        }
    }
}

запустить, не указывая явно его.

$ java  -Xmx256m -XX:+UseG1GC -XX:+PrintStringDeduplicationStatistics jvm.StringDeDuplicationTester
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at jvm.StringDeDuplicationTester.main(StringDeDuplicationTester.java:12)

Запустите, явно включив его.

$ java  -Xmx256m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics jvm.StringDeDuplicationTester
[GC concurrent-string-deduplication, 5116.7K->408.7K(4708.0K), avg 92.0%, 0.0246084 secs]
   [Last Exec: 0.0246084 secs, Idle: 1.7075173 secs, Blocked: 0/0.0000000 secs]
      [Inspected:          130568]
         [Skipped:              0(  0.0%)]
         [Hashed:          130450( 99.9%)]
         [Known:                0(  0.0%)]
         [New:             130568(100.0%)   5116.7K]
      [Deduplicated:       120388( 92.2%)   4708.0K( 92.0%)]
         [Young:                0(  0.0%)      0.0B(  0.0%)]
         [Old:             120388(100.0%)   4708.0K(100.0%)]
   [Total Exec: 1/0.0246084 secs, Idle: 1/1.7075173 secs, Blocked: 0/0.0000000 secs]
      [Inspected:          130568]
         [Skipped:              0(  0.0%)]
         [Hashed:          130450( 99.9%)]
         [Known:                0(  0.0%)]
         [New:             130568(100.0%)   5116.7K]
      [Deduplicated:       120388( 92.2%)   4708.0K( 92.0%)]
         [Young:                0(  0.0%)      0.0B(  0.0%)]
         [Old:             120388(100.0%)   4708.0K(100.0%)]
   [Table]
      [Memory Usage: 264.9K]
      [Size: 1024, Min: 1024, Max: 16777216]
      [Entries: 10962, Load: 1070.5%, Cached: 0, Added: 10962, Removed: 0]
      [Resize Count: 0, Shrink Threshold: 682(66.7%), Grow Threshold: 2048(200.0%)]
      [Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0]
      [Age Threshold: 3]
   [Queue]
      [Dropped: 0]
[GC concurrent-string-deduplication, deleted 0 entries, 0.0000008 secs]
...
output truncated

<суб > Примечание: этот результат от build 1.8.0_131-b11. Похоже, что Java 9 не имеет возможности печатать статистику дедупликации String. Потенциальная ошибка? Нет. Унифицированный журнал убил эту конкретную опцию.

$ java  -Xmx256m -XX:+UseG1GC -XX:+PrintStringDeduplicationStatistics -version
Unrecognized VM option 'PrintStringDeduplicationStatistics'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Ответ 2

Хотя Jigar точно предоставил вам возможность ознакомиться с флагами и статистикой JVM, но для ссылки на некоторые полезные документы, посвященные этой части вопроса:

Я не знаю, где искать документацию за страницей JEP.

В JDK 9 сборщик мусора по умолчанию - G1, когда сборщик мусора явно не указано.

  • Инструмент java, в котором подробно описывается использование флага

    -XX:+UseStringDeduplication
    

Включает дедупликацию строк. По умолчанию этот параметр отключен. к используйте эту опцию, вы должны включить мусор-первый (G1) мусор коллектор.

Дедупликация строк уменьшает объем памяти объектов String на кучу Java, воспользовавшись тем, что многие объекты String идентичны. Вместо каждого объекта String, указывающего на свой собственный массив символов, идентичные объекты String могут указывать и совместно использовать тот же массив символов.


Также рассматривая открытый вопрос, если

Java 9 не имеет возможности печатать статистику дедупликации String.

С JEP 158: Унифицированная реализация JVM Logging в Java9 флаги сборщика мусора помечены как наследие, а альтернативный способ их отслеживания использует -Xlog. Подробный список замены для конвертации флагов регистрации GC в Xlog указан здесь. В одном из них предлагается заменить

PrintStringDeduplicationStatistics  =>   -Xlog:stringdedup*=debug