序
本文主要研究一下G1 GC的String Deduplication
-XX:+UseStringDeduplication
- jdk8u20给G1 GC带来了String Deduplication特性来将相同的字符串指向同一份数据,来减少重复字符串的内存开销
- 该特性默认是关闭的,可以使用-XX:+UseStringDeduplication来开启(
前提是使用-XX:+UseG1GC
) - 具体的实现大致是JVM会记录char[]的weak reference及hash value,当找到一个hash code相同的String时,就会挨个char进行比较,当所有都match,那么其中一个String就会修改指针指向另一个String的char[],这样前者的char[]就可以被回收
实例
实验代码
@Test
public void testG1StringDeduplication() throws InterruptedException {
List<String> data = IntStream.rangeClosed(1,10000000)
.mapToObj(i -> "number is " + ( i % 2 == 0 ? "odd" : "even"))
.collect(Collectors.toList());
System.gc();
long bytes = RamUsageEstimator.sizeOfAll(data);
System.out.println("string list size in MB:" + bytes*1.0/1024/1024);
System.out.println("used heap size in MB:" + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()*1.0/1024/1024);
System.out.println("used non heap size in MB:" + ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed()*1.0/1024/1024);
}
关闭StringDeduplication
-XX:+UseG1GC -XX:-UseStringDeduplication
输出如下:
string list size in MB:586.8727111816406
used heap size in MB:831.772346496582
used non heap size in MB:6.448394775390625
- 整个jvm heap占用了约831MB,其中string list占用了约586MB
开启StringDeduplication
-XX:+UseG1GC -XX:+UseStringDeduplication
输出如下:
string list size in MB:296.83294677734375
used heap size in MB:645.0970153808594
used non heap size in MB:6.376350402832031
- 整个jvm heap占用了约645MB,其中string list占用了约296MB
小结
- jdk8u20给G1 GC带来了String Deduplication特性来将相同的字符串指向同一份数据,来减少重复字符串的内存开销
- 该特性默认是关闭的,可以使用-XX:+UseStringDeduplication来开启(
前提是使用-XX:+UseG1GC
) - 在有大量重复string的前提下,使用G1 GC开启String Deduplication确实能够节省一定的内存,可以节约20%左右的内存,不过这个是理想的情况,因为普通应用里头的string重复的可能不多
doc
- Java 8 String deduplication vs. String.intern()
- JEP 192: String Deduplication in G1
- String Deduplication – A new feature in Java 8 Update 20
- Java 8 Update 20: String Deduplication
- Duplicate Strings: How to Get Rid of Them and Save Memory
- String deduplication feature (from Java 8 update 20)
- G1 GC: Reducing Memory Consumption by 20%
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。