是否默认启用G1垃圾收集器的String Deduplication功能? [英] Is String Deduplication feature of the G1 garbage collector enabled by default?

查看:1183
本文介绍了是否默认启用G1垃圾收集器的String Deduplication功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用Java实现的 JEP 192:G1中的字符串重复数据删除 8 Update 20添加了新的String重复数据删除功能:


通过增强G1垃圾收集器来减少Java堆实时数据集,以便重复实例字符串是自动连续重复数据删除。


JEP页面提到命令行选项 UseStringDeduplication(bool )允许启用或禁用重复数据删除功能。但是JEP页面并没有指出默认值。



➠与Java 8捆绑在一起的G1垃圾收集器中默认的重复数据删除功能是ON还是OFF使用Java 9?



➠是否有getter方法在运行时验证当前设置?



我不知道在JEP页面之外寻找文档的位置。



至少在 HotSpot - 配备了Java 9的实现, G1垃圾收集器 默认启用。这个事实现在促成了这个问题。有关字符串实习和重复数据删除的详细信息,请参阅 Aleksey Shipilev的2014-10演示文稿在29:00。

解决方案

默认情况下字符串重复数据删除关闭



对于下面看到的Java 8和Java 9版本, UseStringDeduplication 默认为 false (禁用)。 / p>

验证功能设置的一种方法:列出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 version1.8.0_131
Java(TM)SE运行时环境(版本1.8.0_131-b11)
Java HotSpot(TM) 64位服务器VM(内置25.131-b11,混合模式)

构建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 version9
Java(TM)SE运行时环境(版本9 + 181)
Java HotSpot(TM)64位服务器VM(内置9 + 181,混合模式)

测试它的另一种方法是使用

  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 
线程中的异常main java.lang.OutOfMemoryError:Java堆空间
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 ,空闲:1.7075173秒,阻止:0 / 0.0000000秒]
[检查:130568]
[跳过:0(0.0%)]
[已散列:130450(99.9%)]
[已知:0(0.0%)]
[新: 130568(100.0%)5116.7K]
[重复数据删除:120388(92.2%)4708.0K(92.0%)]
[年轻:0(0.0%)0.0B(0.0%)]
[旧:120388(100.0%)4708.0K(100.0%)]
[总执行:1 / 0.0246084秒,空闲:1 / 1.7075173秒,阻止:0 / 0.0000000秒]
[检查:130568 ]
[跳过:0(0.0%)]
[哈希:130450(99.9%)]
[已知:0(0.0%)]
[新:130568(100.0) %)5116.7K]
[重复数据删除:120388(92.2%)4708.0K(92.0%)]
[年轻:0(0.0%)0.0B(0.0%)]
[旧: 120388(100.0%)4708.0K(100.0%)]
[表]
[内存使用:264.9K]
[大小:1024,最小值:1024,最大值:16777216]
[参赛作品:10962,载入:1070.5%,缓存:0,已添加:10962,删除:0]
[调整大小计数:0,缩小阈值:682(66 .7%),增长阈值:2048(200.0%)]
[Rehash计数:0,Rehash阈值:120,哈希种子:0x0]
[年龄阈值:3]
[队列]
[丢弃:0]
[GC并发字符串重复数据删除,删除0个条目,0.0000008秒]
...
输出截断


注意:此输出来自 build 1.8。 0_131-B11 。看起来Java 9没有打印字符串重复数据删除统计信息的选项。潜在的错误?
。统一日志记录杀死了此特定选项

  $ java -Xmx256m -XX:+ UseG1GC -XX:+ PrintStringDeduplicationStatistics -version 
无法识别的VM选项'PrintStringDeduplicationStatistics'
错误:无法创建Java虚拟机。
错误:发生致命异常。程序将会退出。


JEP 192: String Deduplication in G1 implemented in Java 8 Update 20 added the new String deduplication feature:

Reduce the Java heap live-data set by enhancing the G1 garbage collector so that duplicate instances of String are automatically and continuously deduplicated.

The JEP page mentions that a command-line option UseStringDeduplication (bool) allows the dedup feature to be enabled or disabled. But the JEP page does not go so far as to indicate the default.

➠ Is the dedup feature ON or OFF by default in the G1 garbage collector bundled with Java 8 and with Java 9?

➠ Is there a "getter" method to verify the current setting at runtime?

I do not know where to look for documentation beyond the JEP page.

In at least the HotSpot-equipped implementations of Java 9, the G1 garbage collector is enabled by default. That fact prompted this Question now. For more info on String interning and deduplication, see this 2014-10 presentation by Aleksey Shipilev at 29:00.

解决方案

String deduplication off by default

For the versions of Java 8 and Java 9 seen below, UseStringDeduplication is false (disabled) by default.

One way to verify the feature setting: list out all the final flags for JVM and then look for it.

build 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)

build 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)

Another way to test it is with

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);
        }
    }
}

run without explicitly specifying it.

$ 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)

Run with explicitly turning it ON.

$ 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

Note: this output is from build 1.8.0_131-b11. Looks like Java 9 has no option to print String de-duplication statistics. Potential bug ? No. Unified logging killed this specific option.

$ 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.

这篇关于是否默认启用G1垃圾收集器的String Deduplication功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆