写点什么

Java 8 新特性:字符串去重

  • 2014-09-11
  • 本文字数:1157 字

    阅读完需:约 4 分钟

8 月 19 日,Oracle发布了JDK 8u20 ,JDK 8u20 包含很多新特性,比如Java 编译器更新、支持在运行时通过API 来修改MinHeapFreeRatio 和MaxHeapFreeRatio 参数、新的GC 调优指南文档。不过在众多新特性中,最令人期待的还是字符串去重(String Deduplication )特性。如何减少内存占用一直是一个永恒的话题,而在Java 应用中,经常会看到String 对象会占用应用30% 的内存,它是Java 中最常用的对象之一。新的字符串去重特性可以帮助减少应用中String 对象的内存占用,目前该特性只适用于G1 垃圾收集器,并且默认不被开启。

Fabian Lange 解释了字符串去重特性的实现方式:

垃圾收集器会在访问 String 对象时对其字符数组进行标记,并将 String 的哈希值以及弱引用保存到一个数组中。当垃圾收集器发现另一个具有相同哈希值的 String 对象时,它就会逐字符比对这两个对象。如果他们完全匹配,那其中一个 String 就会被修改指向到另一个 String 的字符数组。由于第一个字符数组已经不再被引用,所以它也就可以被回收了。垃圾收集器会尽量减少整个操作的开销,比如某个 String 对象扫描未发现有重复,那接下来的一段时间内它不会再被检查。

紧接着,Fabian Lange 通过代码的方式解释了字符串去重特性的神奇效果。首先使用 Java 8 Update 20 通过参数 -Xmx256m -XX:+UseG1GC 运行以下代码:

复制代码
<span>public</span> <span>class</span> LotsOfStrings {
<span>private</span> <span>static</span> final LinkedList<String> LOTS_OF_STRINGS = <span>new</span> LinkedList<>();
<span>public</span> <span>static</span> <span>void</span> <span>main</span>(String[] args) throws Exception {
<span>int</span> iteration = <span>0</span>;
<span>while</span> (<span>true</span>) {
<span>for</span> (<span>int</span> i = <span>0</span>; i < <span>100</span>; i++) {
<span>for</span> (<span>int</span> j = <span>0</span>; j < <span>1000</span>; j++) {
LOTS_OF_STRINGS.add(<span>new</span> String(<span>"String "</span> + j));
}
}
iteration++;
System.<span>out</span>.println(<span>"Survived Iteration: "</span> + iteration);
Thread.sleep(<span>100</span>);
}
}
}

代码会在 30 次循环之后因 OutOfMemoryError 异常而结束运行。在使用参数 -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics 开启字符串去重特性后,程序可以多运行一段时间。通过 JVM 的日志也可以详细了解整个去重过程的详细信息。请读者自行测试。

最后,Fabian Lange 还解释了字符串去重与字符串驻留的区别,它们很相似,除了字符串驻留重用了整个的 String 实例,而字符串去重只是针对 String 的字符数组。

2014-09-11 07:295370
用户头像

发布了 219 篇内容, 共 151.1 次阅读, 收获喜欢 195 次。

关注

评论

发布
暂无评论
发现更多内容

前端【js】学习JavaScrip心得

恒山其若陋兮

5月月更

C++最佳实践 | 4. 可维护性

俞凡

c++ 最佳实践

首届波卡黑客松项目「Manta Network」的进击之路

One Block Community

区块链 隐私安全 黑客马拉松 波卡生态

AI简报-图像质量评价指标-LPIPS

AIWeker

人工智能 深度学习 5月月更

全链路压测(十二):生产压测必不可少的环节

老张

性能测试 全链路压测 稳定性保障

【愚公系列】2022年05月 二十三种设计模式(十四)-命令模式(Command Pattern)

愚公搬代码

5月月更

Cocos Creator学习のTiledMap

空城机

Cocos 5月月更

C++最佳实践 | 3. 安全性

俞凡

c++ 最佳实践

Maven 依赖管理与生命周期

Emperor_LawD

maven 5月月更

是能力更是文化,谈谈IT系统的安全发布

Samson

技术管理 SRE 系统稳定性 安全生产 5月月更

架构实战营 - 第 6 期 模块五课后作业

乐邦

「架构实战营」

Redis「3」持久化

Samson

学习笔记 Redis 核心技术与实战 5月月更

setState 和 ModelBinding用法对比来看局部刷新效果

岛上码农

flutter ios 安卓开发 跨平台开发 5月月更

《原则》读书笔记 - 又臭又长

懒时小窝

读书笔记

ArrayList源码分析-初始化

zarmnosaj

5月月更

14岁懂社会- 《歧视也没什么错》读书笔记 - 丁点思考的车轱辘书

懒时小窝

读书笔记 14岁懂社会

一篇文章带你了解云计算

工程师日月

5月月更

C++最佳实践 | 5. 可移植性及多线程

俞凡

c++ 最佳实践

C语言_链表总结

DS小龙哥

5月月更

SpringBoot之:SpringBoot中使用HATEOAS

程序那些事

Java Spring Boot 程序那些事 5月月更

架构实战营:毕业总结

刘璐

C++最佳实践 | 2. 代码风格

俞凡

c++ 最佳实践

MP4封装格式

Loken

音视频 5月月更

模块1-作业

Fan

架构实战营

一、什么是云原生安全

穿过生命散发芬芳

云原生安全 5月月更

架构实战营:毕业项目《电商秒杀系统》

刘璐

模块1作业回答

Geek_701557

如何保证 Redis 高可用和高并发(主从+哨兵+集群)

Ayue、

redis sentinel Redis 核心技术与实战

【LeetCode】不含重复字符的最长子字符串Java题解

Albert

LeetCode 5月月更

LockSupport与Condition

急需上岸的小谢

5月月更

Laxcus分布式操作系统三代UI演进之路

LAXCUS分布式操作系统

分布式计算 操作系统 分布式存储 并行计算 GUI设计

Java 8新特性:字符串去重_Java_小盖_InfoQ精选文章