Java 编码字符串会占用更少的内存吗?

Java 编码字符串会占用更少的内存吗?,java,encoding,Java,Encoding,我对记忆空间的话题感到困惑。假设我们有以下字符串: String from = "Hello I am from Chicago"; 如果我使用哈夫曼编码、LZ4或GZip等对其进行编码(此时编码算法并不重要): 现在,encodedName所能容纳的内存空间量将小于name所能容纳的内存空间量 我很困惑,因为当我们存储字符串时,即使有更少的位,VM(或操作系统本身,或其他东西)也会在末尾添加填充以完成字节。差不多吧。因此,在一天结束时,编码字符串和未编码字符串的内存大小(而不是消耗量)是相同

我对记忆空间的话题感到困惑。假设我们有以下字符串:

String from = "Hello I am from Chicago";
如果我使用哈夫曼编码、LZ4或GZip等对其进行编码(此时编码算法并不重要):

现在,
encodedName
所能容纳的内存空间量将小于
name
所能容纳的内存空间量

我很困惑,因为当我们存储字符串时,即使有更少的位,VM(或操作系统本身,或其他东西)也会在末尾添加填充以完成字节。差不多吧。因此,在一天结束时,编码字符串和未编码字符串的内存大小(而不是消耗量)是相同的。我这样想对吗

第二个问题与第一个问题有关,我实际上想对1000条记录进行编码,并将其存储在Redis缓存中。如果我们排除压缩/解压缩所需的时间和内存消耗因素,结果会怎样?编码字符串在Redis缓存中占用的空间会更少吗


感谢您的帮助。

压缩一个字符串,然后将压缩结果存储回另一个字符串是一个非常糟糕的主意

按照惯例,字符串是字符序列。它们应该包含字母、标点符号、空格和类似的东西。无论谁发现你用它们来存储二进制数据,他都会生你的气,因为这很不寻常

如果要压缩字符串,请尽可能诚实地将压缩后的数据存储在字节数组中。字节数组是通用容器,可以在其中存储任意数据

回到你的主要问题。在Java中,
String
基本上是一个
char[]
,这意味着每个字符消耗16位(只要您处理的是纯英语字符或来自Java的其他字符)

由于所有字符都是ASCII码,因此每个字符都可以使用7位进行编码。在最前面添加另一位,表示“此字符串的其余部分仅为ASCII”,最终得到一个简单的压缩方案和
1+23*7
位,总计21个字节。当然,在本例中,最后一个字节中有6位填充,但与按原样存储字符串的
2*23
字节相比,这已经很好了

(我只是忘记了:由于Java 9,仅ASCII字符串以一种特殊的方式存储,每个字符仅使用8位,而不是16位。因此,我上面提出的压缩方案只有在Java 8之前才会有效。)


当使用Redis进行数据存储时,请记住,它将所有数据保留在RAM中,一旦无法分配更多RAM,就会崩溃。(据我记忆所及,那是大约5年前的事。)因此,如果你已经可以估计Redis数据会超过几GB,那么最好选择另一个数据存储库。

这实际上取决于使用的编码器。一些编码器在处理少量数据时效果不佳。使用您提到的任何编码器,您显示的短字符串可能不会占用更少的空间。使用这些编码器将数据编码到较小的空间通常需要大约100到200字节的数据,否则您可能会增加所需的空间。此外,如果编码器的结果数据类型是
String
(UTF-16),则空间效率不高。字节数组结果将允许最灵活的压缩算法。顺便说一句,与数据生产者/消费者相比,通常最好在较低的级别上处理压缩。但是,当然,你也可以自己编写较低级别的代码。Hello@RolandIllig,如果redis允许我存储字节,我肯定会使用byte[]。我会在那上面做一些POC。事实上,我有一个很大的json——很多。我想压缩JSON并将其存储在Redis中。此redis不会在内存中运行。它托管在服务器上。
String encodedFrom= encodingLibrary.encode(from);