我有一个使用大量 String
对象的应用程序。我的一个对象(我们称之为 Person
)包含其中 9 个。写入每个String
对象的数据绝不会被写入多次,但之后会被读取多次。在给定时间将有数十万个左右的 Person
对象,并且其中许多 Person
对象将共享名字、姓氏等......
我正在尝试想出直接的方法来减少 Person
对象消耗的内存量,但对于 Java 如何管理其底层内存,我并不是专家。
在我走入这个兔子洞之前,我想知道如果我走这些路会有什么缺点,以及它一开始是否有意义:
- 使用
StringBuilder
或StringBuffer
仅仅是因为trimToSize()
方法可以让我减少在字符串。 - 将字符串存储为
byte[]
数组,并提供一个将byte[]
转换为String
的 getter 和一个将接受String
并转换为byte[]
- 数据被读取相当多,所以这会太昂贵吗? - 为“名称”创建一个哈希表,以防止反复分配(使用指针)相同的名称(可能有数千个包含 10 个以上字符的名称)。
在我毫无意义地走上任何一条道路之前,这样做有意义吗?也许 Java 已经在减少 String
分配并检查重复项?
我也不介意好好读一读。我找到了一些文档,但没有探索到这个深度。
最佳答案
显然 StringBuilder 和 StringBuffer 在这种情况下无济于事。 String 是不可变对象(immutable对象),因此引入这两个类是为了构建 String 而不是为了存储。无论如何,如果您在中间连接/插入字符/从字符串中删除一些字符,您可以(在大多数情况下 - 必须)使用 StringBuilder
在我看来,第二个选项可能会导致内存消耗增加,因为每次需要时将 byte[] 转换为 String 时都会创建新的 String。
Handwriting StringDeduplicator 是非常合理的解决方案,特别是当您陷入 java 5、6、7 困境时。
Java 8/9 具有字符串重复数据删除选项。 By default, this option is disabled 。要在 Java 8 中使用此功能,您必须启用 G1 垃圾收集器,而在 Java 9 G1 is the default 中.
-XX:+UseStringDeduplication
关于字符串去重,请参见:
关于java - 在分配大量字符串数据的应用程序中优化字符串数据的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50747761/