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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31206851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:47:20  来源:igfitidea点击:

How much memory does a string use in Java 8?

javastringmemory

提问by Scartz

I read a lot about memory allocation for Strings lately and can't find any details if things are the same with Java 8.

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

How much memory space would a String like "Alexandru Tanasescu"use in Java 8? I use the 64bit version.

String like"Alexandru Tanasescu"在 Java 8 中使用多少内存空间?我使用的是 64 位版本。

回答by Jordi Castilla

Java7 or lower

Java7 或更低

Minimum String memory usage :

最小字符串内存使用量:

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

So

所以

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


Understanding String memory usage(SOURCE)

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

To understand the above calculation, we need to start by looking at the fields on a String object. A String contains the following:

  • a char array— thus a separate object— containing the actual characters;
  • an integer offset into the array at which the string starts;
  • the length of the string;
  • another int for the cached calculation of the hash code.

This means even if the string contains no characters, it will require 4 bytes for the char array reference, plus 3*4=12 bytes for the three int fields, plus 8 bytes of object header. This gives 24 bytes (which is a multiple of 8 so no "padding" bytes are needed so far).

Then, the (empty) char array will require a further 12 bytes (arrays have an extra 4 bytes to store their length), plus in this case 4 bytes of padding to bring the memory used by the char array object up to a multiple of 16. So in total, an empty string uses 40 bytes.

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

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

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

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

If the Stringcontains, say, 19 characters, then the String object itself still requires 24 bytes. But now the char array requires 12 bytes of header plus 19*2=38 bytes for the seventeen chars. Since 12+38=50 isn't a multiple of 8, we also need to round up to the next multiple of 8 (56). So overall, our 19-character Stringwill use up 56+24 = 80 bytes.

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



Java8.

Java8.

Java 8 does not have the offsetand lengthanymore. Only hashand the CharArray.
@Thomas Jungblut

Java 8 不再有offsetandlength了。只有hashCharArray.
@Thomas Jungblut

  • a char array— thus a separate object— containing the actual characters;
  • an integer offset into the array at which the string starts;
  • the length of the string;
  • another int for the cached calculation of the hash code.
  • 一个字符数组——因此是一个单独的对象——包含实际字符;
  • 字符串开始的数组中的整数偏移量;
  • 字符串的长度;
  • 另一个用于缓存计算哈希码的 int。

So, in Java8 the way to calculate memory for strings remains same but you must subtract 8 bytes less due to the missing offsetand length.

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

回答by Puce

According to the following JEP: http://openjdk.java.net/jeps/254

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

The current implementation of the String class stores characters in a char array, using two bytes (sixteen bits) for each character.

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

In Java SE 9 this might change.

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

Note however, since this is a JEP not a JSR (and it mentions implementation), I understand, that this is implementations specific and not defined by the JLS.

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

回答by Ryan Goldstein

If you look at the Oracle Java 8 sources, you have:

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

A char value[]and an int hash. A charis 2 bytes, and an intis 4 bytes.

Achar value[]int hash. Achar是 2 个字节,anint是 4 个字节。

So wouldn't the answer be yourstring.length* 2 + 4?

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

No. Every object had overhead. An array stores its dimensions, for example. And both the array (an object) and the string will incur extra memory from the garbage collector storing information about them.

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

There is no reliable way to calculate this, because AFAIK each JRE and JDK has no obligation to the size of object overhead.

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

回答by Evgeniy Dorofeev

"Alexandru Tanasescu" uses 104 bytes. This is how to get the size

“Alexandru Tanasescu”使用 104 个字节。这是获取大小的方法

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

Note: run it with -XX:-UseTLAB option

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