Java8新特性之字符串去重介绍
8月19日,Oracle发布了JDK8u20,JDK8u20包含很多新特性,比如Java编译器更新、支持在运行时通过API来修改MinHeapFreeRatio和MaxHeapFreeRatio参数、新的GC调优指南文档。不过在众多新特性中,最令人期待的还属字符串去重(StringDeduplication)。如何减少内存占用一直是一个永恒的话题,而在Java应用中,经常会看到String对象会占用应用30%的内存,它是Java中最常用的对象之一。新的字符串去重特性可以帮助减少应用中String对象的内存占用,目前该特性只适用于G1垃圾收集器,并且默认不被开启。
FabianLange解释了字符串去重特性的实现方式:
垃圾收集器会在访问String对象时对其字符数组进行标记,并将String的哈希值以及弱引用保存到一个数组中。当垃圾收集器发现另一个具有相同哈希值的String对象时,它就会逐字符比对这两个对象。如果他们完全匹配,那其中一个String就会被修改指向到另一个String的字符数组。由于第一个字符数组已经不再被引用,所以它也就可以被回收了。垃圾收集器会尽量减少整个操作的开销,比如某个String对象扫描未发现有重复,那接下来的一段时间内它不会再被检查。
紧接着,FabianLange通过代码的方式解释了字符串去重特性的神奇效果。首先使用Java8Update20通过参数-Xmx256m-XX:+UseG1GC运行以下代码:
publicclassLotsOfStrings{
privatestaticfinalLinkedList<String>LOTS_OF_STRINGS=newLinkedList<>();
publicstaticvoidmain(String[]args)throwsException{ intiteration=0; while(true){ for(inti=0;i<100;i++){ for(intj=0;j<1000;j++){ LOTS_OF_STRINGS.add(newString("String"+j)); } } iteration++; System.out.println("SurvivedIteration:"+iteration); Thread.sleep(100); } } }