gpt4 book ai didi

java - 在 Java 字符(16 位)中存储 UTF-8 字符(8 位)时如何避免内存浪费。二合一?

转载 作者:IT王子 更新时间:2023-10-28 23:38:48 30 4
gpt4 key购买 nike

恐怕我对一个相当过饱和的主题的细节有疑问,我搜索了很多,但找不到一个明确的答案来解决这个特定的明显-imho-重要的问题:

使用UTF-8将byte[]转换为String时,每个字节(8bit)都变成了UTF-8编码的8位字符,但是java中每个UTF-8字符都保存为16位字符。那是对的吗?如果是,这意味着每个愚蠢的 java 字符只使用前 8 位,并消耗双倍的内存?这也正确吗?我想知道这种浪费行为是如何被接受的......

是不是有一些技巧来拥有一个 8 位的伪字符串?这实际上会导致更少的内存消耗吗?或者,有没有办法在一个java 16位字符中存储>两个< 8位字符以避免这种内存浪费?

感谢您提供任何令人困惑的答案...

编辑:你好,谢谢大家的回答。我知道 UTF-8 的可变长度属性。但是,由于我的源是 8 位字节,我理解(显然是错误的)它只需要 8 位 UTF-8 字。 UTF-8 转换是否实际上保存了您在 CLI 上执行“cat somebinary”时看到的奇怪符号?我认为 UTF-8 只是以某种方式用于将字节的每个可能的 8 位字映射到 UTF-8 的一个特定的 8 位字。错误的?我考虑过使用 Base64,但它很糟糕,因为它只使用 7 位..

问题重新表述:有没有更聪明的方法将字节转换为字符串?可能最喜欢的是将 byte[] 转换为 char[],但我仍然有 16 位字。

其他用例信息:

我正在适应 Jedis (NoSQL Redis 的 java 客户端)作为 hypergraphDB 的“原始存储层”。所以,jedis是另一个“数据库”的数据库。我的问题是我必须一直为 jedis 提供 byte[] 数据,但在内部,>Redis<(实际的服务器)只处理“二进制安全”字符串。由于 Redis 是用 C 编写的,因此 char 是 8 位长,AFAIK 不是 7 位的 ASCIII。然而,在 Jedis 和 Java 世界中,每个字符的内部长度都是 16 位。我还不明白这段代码,但我想 jedis 然后将这个 java 16 位字符串转换为符合 Redis 的 8 位字符串(([这里] [3])。它说它扩展了 FilterOutputStream。我希望绕过byte[] <-> 字符串转换并使用那个Filteroutputstream...?)

现在我想知道:如果我必须一直相互转换 byte[] 和 String,数据大小从非常小到可能非常大,将每个 8 位字符传递为java中的16位?

最佳答案

Isn't there some trick to have a pseudo String that is 8 bit?

是的,请确保您拥有最新版本的 Java。 ;)

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

-XX:+UseCompressedStrings Use a byte[] for Strings which can be represented as pure ASCII. (Introduced in Java 6 Update 21 Performance Release)

编辑:此选项在 Java 6 更新 22 中不起作用,并且默认情况下在 Java 6 更新 24 中未启用。注意:似乎此选项可能会使性能降低约 10%。

下面的程序

public static void main(String... args) throws IOException {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
sb.append(i);

for (int j = 0; j < 10; j++)
test(sb, j >= 2);
}

private static void test(StringBuilder sb, boolean print) {
List<String> strings = new ArrayList<String>();
forceGC();
long free = Runtime.getRuntime().freeMemory();

long size = 0;
for (int i = 0; i < 100; i++) {
final String s = "" + sb + i;
strings.add(s);
size += s.length();
}
forceGC();
long used = free - Runtime.getRuntime().freeMemory();
if (print)
System.out.println("Bytes per character is " + (double) used / size);
}

private static void forceGC() {
try {
System.gc();
Thread.sleep(250);
System.gc();
Thread.sleep(250);
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}

默认打印

Bytes per character is 2.0013668655941212
Bytes per character is 2.0013668655941212
Bytes per character is 2.0013606946433575
Bytes per character is 2.0013668655941212

使用选项 -XX:+UseCompressedStrings

Bytes per character is 1.0014671435440285
Bytes per character is 1.0014671435440285
Bytes per character is 1.0014609725932648
Bytes per character is 1.0014671435440285

关于java - 在 Java 字符(16 位)中存储 UTF-8 字符(8 位)时如何避免内存浪费。二合一?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5634855/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com