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);
}
}
}
代码会在30次循环之后因OutOfMemoryError异常而结束运行。在使用参数-XX:+UseStringDeduplication-XX:+PrintStringDeduplicationStatistics开启字符串去重特性后,程序可以多运行一段时间。通过JVM的日志也可以详细了解整个去重过程的详细信息。请读者自行测试。
最后,FabianLange还解释了字符串去重与字符串驻留的区别,它们很相似,除了字符串驻留重用了整个的String实例,而字符串去重只是针对String的字符数组。
(全文完)
相关文章
- linux vim查看下一页,linuxVIM基本命令大全介绍(2)
- Linux系统(根目录下)目录介绍
- 【说站】javascript字符串的语法介绍
- 【说站】Python f-string字符串格式化的介绍
- Python机器学习教程—前传:机器学习介绍(1)
- MongoDB入门教程之常用的运维技术介绍
- 嵌入式Linux:简介与应用(嵌入式linux介绍)
- MySQL课程:简要介绍(mysql课程介绍)
- 管理工具 介绍。(linux系统远程)
- javascript学习笔记(三)String字符串类型介绍
- javascript学习笔记(十二)RegExp类型介绍
- PHP中空字符串介绍0、null、empty和false之间的关系
- php中explode与split的区别介绍
- .net的命名空间类库的简单介绍
- PHP字符串的编码问题的详细介绍
- js将控件隐藏的方法及display属性介绍
- PostgreSQL角色与用户管理介绍
- Mysql字符串处理函数详细介绍、总结
- Swift中初始化方法的顺序介绍