@assylias的回答基本上告诉了您它是如何工作的,并且是非常好的答案。我已经测试了一个使用了String Deduplication的生产应用,并获得了一些结果。这个Web应用程序大量使用字符串,因此我认为优势非常明显。
要启用String Deduplication,您需要添加以下JVM参数(至少需要Java 8u20):
-XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics
最后一个是可选的,但正如其名称所示,它显示了字符串去重的统计信息。这是我的:
[GC concurrent-string-deduplication, 2893.3K->2672.0B(2890.7K), avg 97.3%, 0.0175148 secs]
[Last Exec: 0.0175148 secs, Idle: 3.2029081 secs, Blocked: 0/0.0000000 secs]
[Inspected: 96613]
[Skipped: 0( 0.0%)]
[Hashed: 96598(100.0%)]
[Known: 2( 0.0%)]
[New: 96611(100.0%) 2893.3K]
[Deduplicated: 96536( 99.9%) 2890.7K( 99.9%)]
[Young: 0( 0.0%) 0.0B( 0.0%)]
[Old: 96536(100.0%) 2890.7K(100.0%)]
[Total Exec: 452/7.6109490 secs, Idle: 452/776.3032184 secs, Blocked: 11/0.0258406 secs]
[Inspected: 27108398]
[Skipped: 0( 0.0%)]
[Hashed: 26828486( 99.0%)]
[Known: 19025( 0.1%)]
[New: 27089373( 99.9%) 823.9M]
[Deduplicated: 26853964( 99.1%) 801.6M( 97.3%)]
[Young: 4732( 0.0%) 171.3K( 0.0%)]
[Old: 26849232(100.0%) 801.4M(100.0%)]
[Table]
[Memory Usage: 2834.7K]
[Size: 65536, Min: 1024, Max: 16777216]
[Entries: 98687, Load: 150.6%, Cached: 415, Added: 252375, Removed: 153688]
[Resize Count: 6, Shrink Threshold: 43690(66.7%), Grow Threshold: 131072(200.0%)]
[Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0]
[Age Threshold: 3]
[Queue]
[Dropped: 0]
这是在应用程序运行10分钟后的结果。您可以看到String Deduplication被执行
452次,并且"deduplicated"
801.6 MB的字符串。String Deduplication检查了
27 000 000个字符串。当我将Java 7和标准Parallel GC与启用String Deduplication的Java 8u20和G1 GC进行比较时,堆大约下降了
50%:
Java 7 Parallel GC
Java 8 G1 GC with String Deduplication
![Java 8 G1 GC with String Deduplication](https://istack.dev59.com/tDWnV.webp)
String
,即65536²¹⁴⁷⁴⁸³⁶⁴⁸ == practically infinite
。换句话说,具有相同的哈希码并不保证这些String
是相等的,你需要检查它们是否相等。相反地,有不同的哈希码则意味着这些String
不相等。 - Holgerchar
是一个 16 位的值,所以它允许有2¹⁶ == 65536
种组合。一个String
是一个有着int
长度的序列,因此它最多可以有2³¹
个字符(2³¹
而不是2³²
是因为 Java 中的int
是有符号的,但是String
的大小是正数),所以最大的String
长度是2³¹ == 2147483648
(理论上,实际限制会略小一些)。因此,一个String
最多可以组合达到 2147483648 个字符,每个字符可以有 65536 种可能的组合方式,这使得总共有65536²¹⁴⁷⁴⁸³⁶⁴⁸
种组合方式(实际上可能会稍微多一些,因为一个String
可能也会更短)。 - Holger