在分配相当多字符串数据的应用程序中优化字符串数据的最佳方法



我有一个使用大量String对象的应用程序。我的一个对象(我们称之为Person(包含其中的 9 个。写入每个String对象的数据永远不会写入多次,但会在之后多次读取。在给定的时间,将有几十万个左右的Person对象,其中许多Person对象将共享名字,姓氏等。

我正在尝试想一些直接的方法来减少Person对象消耗的内存量,但是当涉及到Java如何管理其下面的内存时,我不是专家。

在我进入这个兔子洞之前,我想知道如果我沿着这些道路走下去会有什么缺点,以及它是否首先有意义:

  • 使用StringBuilderStringBuffer仅仅是因为trimToSize()方法允许我减少字符串中使用的分配字节数。
  • 将字符串存储为数组byte[]并提供一个将byte[]转换为String的 getter 和一个接受String并转换为byte[]的 setter - 数据正在被读取很多,所以这会不会太贵了?
  • (让我们说("名称"创建一个哈希表,以防止一遍又一遍地为同一名称重复分配(使用指针((可能有数千个名称具有 10+ 个字符(。

在我毫无意义地走上这些道路之前,这样做有意义吗?也许Java已经在减少String分配并检查重复项?

我也不介意好好读一读。我找到了一些文档,但没有深入探讨的内容。

  1. 显然,在这种情况下,StringBuilder和StringBuffer无法提供帮助。字符串是不可变的对象,因此引入这两个类是为了构建字符串而不是用于存储。无论如何,如果您连接/在中间插入字符/从字符串中删除一些字符,您可以(在大多数情况下 - 必须(使用 StringBuilder

  2. 在我看来,第二个选项可能会导致内存消耗增加,因为每次您需要 byte[] 时都会创建新的字符串。

  3. 手写的StringDeduplicator是非常合理的解决方案,特别是如果你坚持使用java 5,6,7。

  4. Java 8/9 具有字符串重复数据删除选项。默认情况下,此选项处于禁用状态。要在 Java 8 中使用这个垃圾回收器,您必须启用 G1 垃圾回收器,而在 Java 9 中,G1 是默认的。

    -XX:+使用字符串重复数据删除

有关字符串重复数据删除,请参阅:

  • JEP 192:G1 中的字符串重复数据删除
  • Java 8 更新 20 发行说明
  • 其他堆栈溢出帖子

最新更新