阅读更多

3顶
0踩

编程语言

字符串在任何应用中都占用了大量的内存。尤其数包含独立UTF-16字符的char[]数组对JVM内存的消耗贡献最多——因为每个字符占用2位。

 

内存的30%被字符串消耗其实是很常见的,不仅是因为字符串是与我们互动的最好的格式,而且是由于流行的HTTP API使用了大量的字符串。使用Java 8 Update 20,我们现在可以接触到一个新特性,叫做字符串去重,该特性需要G1垃圾回收器,该垃圾回收器默认是被关闭的。

 

字符串去重利用了字符串内部实际是char数组,并且是final的特性,所以JVM可以任意的操纵他们。

 

对于字符串去重,开发者考虑了大量的策略,但最终的实现采用了下面的方式:

 

无论何时垃圾回收器访问了String对象,它会对char数组进行一个标记。它获取char数组的hash value并把它和一个对数组的弱引用存在一起。只要垃圾回收器发现另一个字符串,而这个字符串和char数组具有相同的hash code,那么就会对两者进行一个字符一个字符的比对。

 

如果他们恰好匹配,那么一个字符串就会被修改,指向第二个字符串的char数组。第一个char数组就不再被引用,也就可以被回收了。

 

这整个过程当然带来了一些开销,但是被很紧实的上限控制了。例如,如果一个字符未发现有重复,那么一段时间之内,它会不再被检查。

 

那么该特性实际上是怎么工作的呢?首先,你需要刚刚发布的Java 8 Update 20,然后按照这个配置: -Xmx256m -XX:+UseG1GC 去运行下列的代码: 


这段代码会执行30个迭代之后报OutOfMemoryError。 

 

现在,开启字符串去重,使用如下配置去跑上述代码: 

 

-Xmx256m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics 

 

此时它已经可以运行更长的时间,而且在50个迭代之后才终止。 

 

JVM现在同样打印出了它做了什么,让我们一起看一下: 


为了方便,我们不需要自己去计算所有数据的加和,使用方便的总计就可以了。 

 

上面的代码段规定执行了字符串去重,花了16ms的时间,查看了约 120 k 字符串。 

 

上面的特性是刚推出的,意味着可能并没有被全面的审视。具体的数据在实际的应用中可能看起来有差别,尤其是那些应用中字符串被多次使用和传递,因此一些字符串可能被跳过或者早就有了hashcode(正如你可能知道的那样,一个String的hash code是被懒加载的)。

 

在上述的案例中,所有的字符串都被去重了,在内存中移除了4.5MB的数据。

 

[Table]部分给出了有关内部跟踪表的统计信息,[Queue]则列出了有多少对去重的请求由于负载被丢弃,这也是开销减少机制中的一部分。

 

那么,字符串去重和字符串驻留相比又有什么差别呢?我博客上有一篇文章,名叫how great String Interning is for memory efficiency 。事实上,字符串去重和驻留看起来差不多,除了暂留的机制重用了整个字符串实例,而不仅仅是字符数组。

 

JDK Enhancement Proposal 192的创造者的争论点在于开发者们常常不知道将驻留字符串放在哪里合适,或者是合适的地方被框架所隐藏.就像我写的那样,当碰到复制字符串(像国家名字)的时候,你需要一些常识.字符串去重,对于在同一个JVM中的应用程序的字符串复制也有好处,同样包括像XML Schemas,urls以及jar名字等一般认为不会出现多次的字符串.

 

当字符串驻留发生在应用程序线程中的时候,垃圾回收异步并发处理时,字符串去重也不会增加运行时的消耗.这也解释了,为什么我们会在上面的代码中发现Thread.sleep().如果没有sleep会给GC增加太多的压力,这样字符串去重根本就不会发生.但是,这只是示例代码才会出现的问题.实际的应用程序,常常会在运行字符串去重的时候使用几毫秒的时间.

 

  • 大小: 22.4 KB
  • 大小: 431.1 KB
3
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • lucene scorer

    } } opt 如果optional的size 为1直接返回 如果大于1 生成optionalScorers,使用optional,生成score放入其中 如果minShouldMatch大于1生成MinShouldMatchSumScorer 否则 且scoreMode 为TOP_SCORES则生成WANDScorer ...

  • Lucene总结三:Lucene的索引文件格式(1)

    Lucene的搜索过程,就是按照此文件格式将索引进去的信息读出来,然后计算每篇文档打分(score)的过程。 本文详细解读了Apache Lucene - Index File Formats(http://lucene.apache.org/java/2_9_0/fileformats.html) ...

  • java中score用法,Lucene 8.x 使用 FunctionScoreQuery 实现自定义的文档评分

    在使用不管是 Lucene 或者 ElasticSearch 进行全文搜索中,检索到文档很简单,但是把搜索者最想要的结果排在最前面,这是最具挑战性的。我们举个最简单的例子:假设我们需要做一个博客搜索,当我们用 Lucene 默认的...

  • Lucene

    缺点:1、数据量大时查询性能差(不会通过索引查询);2、查询的结果不够全面。 全文检索方案 缺点:使用相对复杂,通过提供的API进行操作。 优点:1、数据量大时查询性能好;2、查询的结果全面 应用场景 ...

  • ElasticSearch教程(Lucene)

    二、ES概述 2.1 ES的介绍 ES是一个使用Java语言并且基于Lucene编写的搜索引擎框架,他提供了分布式的全文搜索功能,提供了一个统一的基于RESTful风格的WEB接口,官方客户端也对多种语言都提供了相应的API。 Lucene...

  • lucene入门介绍篇

    1.lucene介绍 (1)简介 lucene是最受欢迎的java开源全文搜索引擎开发工具包。lucene使用反向索引,提供了完整的查询引擎和索引引擎,部分文本分词引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,...

  • Lucene之MaxScorer算法简介

    简介  名叫“Lucene之MaxScorer算法分析”其实并不准确,因为有Stefan提交的MaxScorer代码尚未提交到Lucene,至今还在讨论中,具体见:...目前Lucene对于MaxScore的计算,

  • Lucene打分公式详解(TFIDFSimilarity)

    本文章基于Lucene5.5,对其默认使用的打分公式(TFIDFSimilarity)进行解析 一、余弦相似度算法 由于网络上有很多关于VSM(向量空间模型)的解释,这里就不花费篇章做基本理论的描述了,只总结一下算法即可。给定两个...

  • lucene详细介绍

    1 lucene简介  1.1 什么是lucene  项目地址: https://github.com/apache/lucene-solr Lucene是一个全文搜索框架,而不是应用产品。它只是提供了一种工具让你能实现这些产品。 它的特点概述起来就是:全Java...

  • Lucene检索源码解析(下)

    float score = scorer.score(); totalHits++; if (score <= pqTop.score) { return; } //真实的docId需要当前reader的docBase加上doc(相当于偏移量) pqTop.doc = doc + docBase; pqTop.score = score; //...

  • java es score_es score限制

    背景在搜索个性化改造中,由于个性化打分耗时较长,所以不能对...原先的排序逻辑为 A字段、function A(自定义相关性打分)、B字段、C字段 使用sort机制进行排序,但是rescore是基于score机制,两者只能取一种逻辑排...

  • Lucene&ElasticSeach&Kafka

    1 什么是全文检索 1.1 数据分类 生活中的数据总体分为两种:结构化数据和非结构化数据。 ​ 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等 ​ 非结构化数据:指不定长或无固定格式的数据,如...

  • Java:91-Lucene+ElasticSeach核心技术

    为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能 Lucene适用场景: 在应用中为数据库中的数据提供全文检索实现,开发独立的搜索引擎服务、系统 Lucene的特性: 1:稳定、索引性能...

  • Lucene 评分机制

    在检索文档时,lucene会计算文档与查询语句之间的相似程度,以打分的形式来表示,分值越高,相似度和匹配度越高。计算分值的公式如下: score(q,d) = coord(q,d) · queryNorm(q) · ∑ ( tf(t...

  • Lucene学习总结之三:Lucene的索引文件格式(1)

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的...Lucene的搜索过程,就是按照此文件格式将索引进去的信息读出来,然后计算每篇文档打分(score)的过程。 本文详细解读了

  • lucene 的使用详情

    这是一篇关于lucene的讲解非常细的一篇文章,有助于大家对lucene更快的了解,

  • Lucene 基本原理(四)索引的构成

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源... Lucene的搜索过程,就是按照此文件格式将索引进去的信息读出来,然后计算每篇文档打分(score)的过程。 本文详细解读了Apach...

  • 全文检索及Lucene及elasticsearch详解

    Lucene 实现全文检索的流程 创建索引 获得文档 1. 原始文档:要基于哪些数据来进行搜索,那么这些数据就是原始文档 2. 搜索引擎:使用爬虫获取原始文档 3. 站内搜索:数据库中的数据 案例:直接使用io读取到磁盘上的...

  • Lucene教程详解

    注明:本文是由本人在开发有关基于lucene资源检索系统时的一点总结,其中一部分是自己根据开发过程自己总结的,也有部分是摘自网络,因无法获取当时摘文的地址,所以在此没有写源地址。 转载请声明出处   ...

  • 果壳处理器研究小组(Topic基于RISCV64果核处理器的卷积神经网络加速器研究)详细文档+全部资料+优秀项目+源码.zip

    【资源说明】 果壳处理器研究小组(Topic基于RISCV64果核处理器的卷积神经网络加速器研究)详细文档+全部资料+优秀项目+源码.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

Global site tag (gtag.js) - Google Analytics