繁体   English   中英

Java 8 中的字符串使用多少内存?

[英]How much memory does a string use in Java 8?

我最近阅读了很多关于字符串内存分配的内容,如果 Java 8 的情况相同,则找不到任何详细信息。

"Alexandru Tanasescu"这样的字符串在 Java 8 中会使用多少内存空间? 我使用的是 64 位版本。

Java7或更低

最小字符串内存使用量:

(bytes) = 8 * (int) ((((no chars) * 2) + 45) / 8)

所以

80 = 8 * (int) ((((19) * 2) + 45) / 8)

了解字符串内存使用情况( SOURCE )

要理解上述计算,我们需要从查看 String 对象上的字段开始。 一个字符串包含以下内容:

  • 一个包含实际字符的 char 数组——因此是一个单独的对象;
  • 字符串开始的数组中的整数偏移量;
  • 字符串的长度;
  • 另一个用于缓存计算哈希码的 int。

这意味着即使字符串不包含字符,它也需要 4 个字节用于 char 数组引用,加上 3*4=12 个字节用于三个 int 字段,再加上 8 个字节的对象头。 这给出了 24 个字节(这是 8 的倍数,因此到目前为止不需要“填充”字节)。

然后,(空)char 数组将需要另外 12 个字节(数组有额外的 4 个字节来存储它们的长度),在这种情况下加上 4 个字节的填充,以使 char 数组对象使用的内存达到16. 因此,一个空字符串总共使用 40 个字节。

如果String包含 19 个字符,那么 String 对象本身仍然需要 24 个字节。 但是现在 char 数组需要 12 个字节的标题加上 19*2=38 个字节的 17 个字符。 由于 12+38=50 不是 8 的倍数,我们还需要四舍五入到下一个 8 的倍数 (56)。 所以总的来说,我们的 19 个字符的String将使用 56+24 = 80 个字节。


Java8。

Java 8 不再有offsetlength 只有hashCharArray
@Thomas Jungblut

  • 一个包含实际字符的 char 数组——因此是一个单独的对象;
  • 字符串开始的数组中的整数偏移量;
  • 字符串的长度;
  • 另一个用于缓存计算哈希码的 int。

因此,在 Java8 中,计算字符串内存的方式保持不变,但由于缺少offsetlength ,您必须少减去 8 个字节。

如果您查看 Oracle Java 8 源代码,您会发现:

一个char value[]和一个int hash 一个char是 2 个字节,一个int是 4 个字节。

那么答案不是yourstring.length * 2 + 4 吗?

不,每个对象都有开销。 例如,数组存储其维度。 并且数组(一个对象)和字符串都会从垃圾收集器中产生额外的内存来存储有关它们的信息。

没有可靠的方法来计算这一点,因为 AFAIK 每个 JRE 和 JDK 对对象开销的大小没有义务。

“Alexandru Tanasescu”使用 104 个字节。 这是如何获得大小

    long m0 = Runtime.getRuntime().freeMemory();
    String s = new String("Alexandru Tanasescu");
    long m1 = Runtime.getRuntime().freeMemory();
    System.out.println(m0 - m1);

注意:使用 -XX:-UseTLAB 选项运行它

根据以下JEP:http: //openjdk.java.net/jeps/254

String 类的当前实现将字符存储在 char 数组中,每个字符使用两个字节(16 位)。

在 Java SE 9 中,这可能会改变。

但是请注意,由于这是 JEP 而不是 JSR(并且它提到了实现),我理解这是特定于实现的,而不是由 JLS 定义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM