@assylias答案基本上会告诉您它是如何工作的,这是一个很好的答案。我已经用String Deduplication测试了生产应用程序,并得到了一些结果。Web应用程序大量使用Strings,因此我认为优势非常明显。
要启用字符串重复数据删除,您必须添加以下JVM参数(至少需要Java 8u20):
-XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics
最后一个是可选的,但正如名称所示,它显示了String Deduplication统计信息。这是我的:
[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分钟后的结果。如您所见,字符串重复数据删除已执行452次,并已“重复数据删除” 801.6 MB字符串。串重复数据删除检查27个000 000字符串。当我比较使用标准Parallel GC的Java 7和使用G1 GC的Java 8u20的内存消耗并启用String Deduplication时,堆的内存下降了大约50%:
Java 7并行GC
具有字符串重复数据删除功能的Java 8 G1 GC
2³² == 4294967296
不同的哈希码,但65536²¹⁴⁷⁴⁸³⁶⁴⁸ == practically infinite
可能有不同String
的。换句话说,具有相同的哈希码不能保证String
相等。你必须检查一下。唯一相反的是,具有不同的哈希码意味着String
s不相等。