Java 中 String 享元实现的最佳替代方案

2024-02-11

我的应用程序是多线程的,具有密集的字符串处理。我们遇到内存消耗过多的情况,分析表明这是由字符串数据引起的。我认为使用某种享元模式实现甚至缓存会极大地提高内存消耗(我确信字符串经常是重复的,尽管我在这方面没有任何硬数据)。

我研究过 Java Constant Pool 和 String.intern,但似乎它会引发一些 PermGen 问题。

在 java 中实现应用程序范围的多线程字符串池的最佳替代方案是什么?

编辑:另请参阅我之前的相关问题:java 如何在幕后实现字符串的享元模式? https://stackoverflow.com/questions/2909848


注意:此答案使用的示例可能与现代运行时 JVM 库不相关。特别是,substring在 OpenJDK/Oracle 7+ 中示例不再是问题。

我知道这与人们经常告诉你的相反,但有时会明确地创造新的String实例can是减少记忆力的重要方法。

由于字符串是不可变的,因此有几种方法利用这一事实并共享支持字符数组以节省内存。但是,有时这实际上可以通过防止对这些数组的未使用部分进行垃圾收集来增加内存。

例如,假设您正在解析日志文件的消息 ID 以提取警告 ID。你的代码看起来像这样:

//Format:
//ID: [WARNING|ERROR|DEBUG] Message...
String testLine = "5AB729: WARNING Some really really really long message";

Matcher matcher = Pattern.compile("([A-Z0-9]*): WARNING.*").matcher(testLine);
if ( matcher.matches() ) {
    String id = matcher.group(1);
        //...do something with id...
}

但看看实际存储的数据:

    //...
    String id = matcher.group(1);
    Field valueField = String.class.getDeclaredField("value");
    valueField.setAccessible(true);

    char[] data = ((char[])valueField.get(id));
    System.out.println("Actual data stored for string \"" + id + "\": " + Arrays.toString(data) );

这是整个测试行,因为匹配器只是将新的 String 实例包装在相同的字符数据周围。更换时比较结果String id = matcher.group(1); with String id = new String(matcher.group(1));.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中 String 享元实现的最佳替代方案 的相关文章

  • 以编程方式将字符串宽度值插入到 sprintf() 中

    我正在尝试以编程方式将字符串宽度值插入到sprintf 格式 期望的结果是 sprintf 20s hello 1 hello 但我想插入20在同一通话中即时进行 因此它可以是任何号码 我努力了 sprintf ds 20 hello 1
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List

随机推荐

  • 块与 Objective-C 中的普通方法和函数有何不同?

    与 Objective C 中的普通方法和函数相比 使用块有什么优势 我已阅读文档 但找不到块而不是其他语言功能的具体用法 我确信我错过了一些东西 所以有人可以用比现有文档更简单的方式解释块的优点吗 块是一种包装一段代码并有效存储它以供以后
  • 将 Angularjs 和 Rails 应用程序分离为独立组件

    我想尝试一下 Angularjs 然而 我一直难以决定应该将我的角度应用程序放在哪里 我使用 Rails 框架作为后端 我看过教程 其中整个角度应用程序都位于 asset javascript 文件夹下 我想知道是否可以让它完全位于我的ra
  • Tailwind CSS:有没有办法定位下一个兄弟?

    我有一个带有如下标签的无线电输入 输入被隐藏 标签用于制作一个视觉上吸引人的圆圈供用户单击
  • receiveCompletion 出错时订阅取消

    在我的以 MVVM 模式设计的应用程序中 我有一个登录视图 如果存在网络或身份验证问题 登录可能会失败 我的目标是捕获错误并显示相应的警报 我为警报定义了枚举 如下所示 enum Alerts Identifiable var id Int
  • Application Insights 是否跟踪引荐来源网址?

    我想我到处查看和搜索 但找不到任何带有推荐流量数据的图表或报告 我使用的是在预览 Azure 门户中存储数据的最新版本 在旧的应用程序洞察中 即在 VS Online 中 有此数据 有谁知道在新门户中是否可以找到它以及在哪里可以找到它 提前
  • Centos 7 Postgres 服务的环境变量

    最近我遇到了使用自定义 PGDATA 路径启动 postgresql 服务的问题 它尝试查找未初始化的默认数据目录 var lib pgsql 9 3 data 因此触发了这些错误 问题似乎是 Centos 7 上的服务启动器删除了所有环境
  • 如何在 Android 上将文件从内部应用程序存储移动/重命名到外部存储?

    我正在从互联网下载文件并将流数据保存到我的应用程序内部存储中的临时文件中获取文件目录 http developer android com reference android content Context html getFilesDir
  • IllegalArgumentException:类 TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean 中没有可见的构造函数

    我正在尝试使用 h2 数据库为 Spring Boot JPA 应用程序编写集成测试 不知何故 TestEntityManager 没有被创建 我尝试在论坛上寻找一些帮助 但找不到任何相关信息 感谢任何人可以提供帮助或提供一些指导 Than
  • 将 wc 行附加到文件名

    标题说明了一切 我已经设法得到这样的行 lines wc file txt awk print 1 但我可以使用辅助功能将其附加到文件名中 向我展示如何循环遍历当前目录中的所有 txt 文件的奖励积分 find name txt execd
  • 在 mac、ios、linux 上使用 calibri 风格

    由于 Windows 操作系统中存在 calibri 样式 但 linux mac ios 中不存在 calibri 样式 如果我的项目仅在 calibri 中具有其样式 并且我必须严格使用它 那么如果用户使用linux 并运行我的项目 那
  • 在android中使用Geocoder获取地址

    我尝试通过提供静态地理坐标来获取特定位置的地址 我无法获取地址 有人可以帮忙吗 我只需要检查这个功能是否适合我 这是我的片段 Geocoder geocoder new Geocoder AddressSimulator this Loca
  • 如何使用 docker-compose 将环境变量设置到 docker 容器中

    我想设置凭据以使用 Google Translate Api 客户端 因此我必须设置环境变量GOOGLE APPLICATION CREDENTIALS该值是凭证文件的路径 来自 Google Cloud 当我被利用的时候docker bu
  • 将未知长度的 char** (c) 转换为 vector (c++) [重复]

    这个问题在这里已经有答案了 如何将 C char 转换为 C 矢量 是否有一些内置功能可以用来做到这一点 或者通过一系列迭代步骤来完成它是否更好 编辑 由于各种原因 C 数组中的元素数量未知 我可以将其作为另一个参数传递 但这绝对有必要吗
  • 如何在反应中使用复选框形式?

    有两个组件container and presenter 下面的代码显示单个复选框状态变为 true 并且另一个复选框也正在更新 那么 如何处理具有状态的多个复选框 容器 export default class ApplyFormCont
  • 为什么点击设置innerHTML会在Chrome上触发两个解析事件?

    使用Chrome开发者工具中的时间轴 我使用了这一小段代码来记录事件内部HTML
  • 如何分发 Android 库

    我一直在为 android 库项目旋转一个 jar 并将这个 jar 包含在我的其他应用程序中 但在developer android com上 http developer android com tools projects index
  • REST API 404:URI 错误或缺少资源?

    我正在构建 REST API 但遇到了问题 设计 REST API 时公认的做法似乎是 如果请求的资源不存在 则返回 404 然而 对我来说 这增加了不必要的歧义 传统上 HTTP 404 与错误的 URI 相关 所以实际上我们是说 要么你
  • 将 ILMerge 与 .NET 4 库结合使用

    两个问题 1 基本 NET 程序集不包含在 ILMerged 程序集中 从 NET 3 5 Visual Studio 2008 升级到 NET 4 Visual Studio 2010 后 我在构建后使用 ILMerge 时遇到问题 我有
  • 以列表作为参数的 defun

    我正在尝试选择 Lisp 作为我的新语言 但我在解决如何让函数的一部分作用于传递给它的列表的每个元素上时遇到了一些问题 为了学习如何解决这个问题 我试图编写一个相当基本的除法形式 当列表的一个元素为 0 时不会发出声音 而是只返回 0 de
  • Java 中 String 享元实现的最佳替代方案

    我的应用程序是多线程的 具有密集的字符串处理 我们遇到内存消耗过多的情况 分析表明这是由字符串数据引起的 我认为使用某种享元模式实现甚至缓存会极大地提高内存消耗 我确信字符串经常是重复的 尽管我在这方面没有任何硬数据 我研究过 Java C