百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

聊聊Java String.intern 背后你不知道的知识

toyiye 2024-05-19 19:36 27 浏览 0 评论

导读:String.intern是一个JDK中的常用方法,通常用于缓存字符串,优化内存使用,然而频繁使用该方法也会导致别的问题,本文从该方法的实现入手,深入分析了可能出现的问题和解决方案。

Java的 String类有个有意思的public方法:

public String intern

返回标准表示的字符串对象。String类维护私有字符串池。

调用此方法时,如果字符串池已经包含等于此字符串对象的字符串(通过equals方法确定),则返回池中的字符串。 否则,将此String对象添加到池中,并返回对此String对象的引用。

这个功能为String提供了字符串池,我们可以使用它来优化内存。 但是,这有一个缺点:在OpenJDK中,String.intern是本地方法,它实际上调用了JVM的相关方法来实现该功能。这样实现的原因是,当VM和JDK代码必须就特定String对象的标识达成一致时,String interning就必须是JDK-VM接口的一部分。

这样的实现意味着:

  1. 您需要在每个intern调用使用JDK-JVM接口,这会浪费CPU。

  2. 性能受本地HashTable实现的影响,可能落后于高性能Java版本,特别是在并发访问的情况下。

  3. 由于Java Strings是来自VM的引用,因此它们成为GC root set的一部分。 在许多情况下,这需要在GC停顿期间执行额外的工作。

吞吐量实验

我们可以构建简单的实验来说明问题。 使用HashMap和ConcurrentHashMap实现intern方法,这为我们提供了一个非常好的JMH基准:

该测试试图在很多字符串上执行intern方法,但实际的intern仅在第一次遍历循环时发生,之后只访问map中的字符串。 size参数用于控制我们intern的字符串数量,从而限制我们正在处理的字符串表大小。 对于intern来说,通常都这样使用。

使用JDK 8u131运行它:

可以看出 String.intern明显更慢。慢的原因在于本地实现,这在perf record -g中清晰可见:

虽然JNI转换成本相当高,但似乎在StringTable实现上也花了相当多的时间。 使用 -XX:+PrintStringTableStatistics,将输出如下内容:

注意最后一行,平均每个bucket 16个元素表示已经过载。 更糟糕的是,字符串表不可调整大小(虽然有实验工作使它们可以调整大小,但是因为“其他原因”而被移除)。 通过设置更大的-XX:StringTableSize可能会减轻该问题:

然而这只能暂时缓解问题,因为你必须提前做好规划。 如果盲目地将String表大小设置为较大值,并且不使用它,则会浪费内存。 即使您使用很大的StringTable,JNI本地调用仍然会消耗CPU。

GC停顿实验

本地字符串表最大问题在于它是GC root的一部分。也就是说,它应该需要垃圾收集器进行特殊扫描/更新。 在OpenJDK中,这意味着在暂停期间额外工作。 实际上,对于Shenandoah(译者注:对于ZGC也如此),暂停主要依赖于GC root set大小,在String表中存在1M记录会导致以下结果:

因为我们在root set中添加了内容,每次暂停会增加13ms。

某些GC实现仅在完成重要操作时执行String表清理。 比如,如果不进行卸载类,从JVM角度来看清理String表是没有意义的(因为加载的类是intern字符串的主要来源)。 因此,此工作负载在G1和CMS中会也会表现出有趣的行为:

用CMS跑一遍:

看起来结果还可以。 遍历重载的字符串表需要一段时间。 蛋疼的事情会在使用-XX:-ClassUnloading禁用类卸载后发生。你猜猜接下来会发生什么:

FULL GC! 对于CMS,假设用户会调用System.gc,使用ExplicitGCInvokesConcurrentAndUnloadsClasses会缓解这一情况。

意见

在假设改进内存占用空间或低级==优化的情况下,我们讨论了实现intern的方法。有关Java String的更多详细信息,可以参考我的演讲“java.lang.String Catechism”。

对于OpenJDK,String.intern是本机JVM字符串表的代理,使用它需要注意:吞吐量,内存占用,暂停时间等问题。 很容易低估这些问题的影响。 手动控制的intern工作更加可靠,因为它们在Java端工作,只是普通Java对象,通常更容易调整大小,并且在不再需要时也可以完全丢弃。 GC辅助字符串去重复数据(http://openjdk.java.net/jeps/192)确实可以减少很多问题。

几乎在在我们进行每个项目中,从热路径中删除String.intern,或者用手动方式替代它,都有很大的性能提升。 不要无脑使用String.intern,好吗?

原文地址:

https://shipilev.net/jvm/anatomy-quarks/10-string-intern/

本文作者Aleksey Shipilёv,由方圆翻译。转载本文请注明出处,欢迎更多小伙伴加入翻译及投稿文章的行列,详情请戳公众号菜单「联系我们」。

参考阅读:

  • 为何服务器QPS上不去?Java线程调优权威指南

  • C++ Python PHP Java NodeJS性能大PK,结果PHP7是最……

  • 一文读懂Java 11的ZGC为何如此高效

  • 5分钟学会Java 9~Java11的七大新特性

  • Java性能优化指南及唯品会的实战

技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。

高可用架构

改变互联网的构建方式

长按二维码 关注「高可用架构」公众号

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码