【发布时间】:2015-03-13 00:09:54
【问题描述】:
由于 Java 中的 String(与其他语言一样)由于每个字符占用两个字节而消耗大量内存,因此 Java 8 引入了一个名为字符串重复数据删除的新功能它利用了 char 数组在字符串和 final 的内部这一事实,因此 JVM 可以处理它们。
到目前为止,我已经阅读了this example,但由于我不是专业的 Java 编码器,所以我很难理解这个概念。
这就是它所说的,
已经考虑了字符串复制的各种策略,但是 现在实施的方法遵循以下方法:每当 垃圾收集器访问 String 对象,它记下 char 数组。它获取它们的哈希值并将其与弱 对数组的引用。一旦它找到另一个字符串 相同的哈希码将它们逐个字符地进行比较。如果它们匹配为 好吧,一个 String 将被修改并指向 char 数组 第二个字符串。然后不再引用第一个 char 数组 不再存在,可以被垃圾收集。
这整个过程当然会带来一些开销,但是是可控的 通过严格的限制。例如,如果一个字符串没有被发现有 重复一段时间就不再检查了。
我的第一个问题,
由于最近在 Java 8 更新 20 中添加了该主题,因此仍然缺乏资源,这里有人可以分享一些实际示例,说明它如何帮助减少 Java 中 String 消耗的内存吗?
编辑:
上面的链接说,
一旦找到另一个具有相同哈希码的字符串 逐个字符比较它们
我的第二个问题,
如果两个String的哈希码相同,那么Strings已经相同,那为什么要在发现两个String的哈希码相同时,用char比较char呢?
【问题讨论】:
-
你听说过“哈希冲突”吗?只有
2³² == 4294967296不同的哈希码,但65536²¹⁴⁷⁴⁸³⁶⁴⁸ == practically infinite可能有不同的Strings。换句话说,具有相同的哈希码不保证String相等。你必须检查一下。恰恰相反,具有不同的哈希码意味着Strings 不相等。 -
我没有链接,因为很容易找到:一个
char是一个16位的值,所以它允许2¹⁶ == 65536组合。String是一个长度为int的序列,因此它最多可以有2³¹个字符(2³¹不是2³²,因为int是用 Java 签名的,但String的大小是正数) 所以String的最大长度是2³¹ == 2147483648(理论上,实际的限制要小一些)。所以String最多可以组合 2147483648 个字符,这些字符可以有 65536 种可能的组合,这使得65536²¹⁴⁷⁴⁸³⁶⁴⁸组合(实际上有点大,因为String也可能更短) -
@mbomb007:当有
m不同的数字允许mⁿ组合时,就像有一个带有n数字位置的数字一样,例如从000到999的十进制数字允许10³组合。对于String,在2147483648数字位置有65536不同的“数字”(又名chars),所以它是65536²¹⁴⁷⁴⁸³⁶⁴⁸。它只是“稍微”多一点,因为\0和“end-of-String”在 Java 中是不同的。这并不重要,因为它太大了,无法想象。 -
它应该等于 (2¹⁶)^(∑ n=0_31(2^n)) 如果你包含一个可以更短的
String。我正是这个意思。这实际上并没有更多。 -
相等的哈希码并不意味着相等的字符串。见stackoverflow.com/questions/27581/…