【问题标题】:How is memory allocated for a string?如何为字符串分配内存?
【发布时间】:2012-07-10 02:52:52
【问题描述】:

在 Java 或 C++ 中,如何为字符串分配内存?这可能是愚蠢的,所以请原谅我。我想知道,因为字符串的大小未知。

【问题讨论】:

  • "a string is unknown size": 不在 Java 中。
  • 一个字符串实际上永远不会是未知大小的,无论它是否不可变。
  • 如上文档所示,对于Hotspot JVM 6:“最小字符串内存使用量(字节)= 8 *(int)((((无字符)* 2)+ 45)/ 8) "

标签: java c++ string memory-management


【解决方案1】:

在 Java 中,String 是一个不可变对象,因此 String 的“大小”必须在分配时知道。如果它是“静态的”(例如String litteral,如"Hey, I'm a String litteral!"),它将最终分配在共享对象池中,或者如果它是使用new String(...) 构造的,则分配在堆上。

【讨论】:

    【解决方案2】:

    Java 字符串是不可变的对象。在某种程度上,每次您创建一个字符串时,都会为字符串中的字符数分配 char[] 内存。如果您对该字符串进行任何操作,它将是全新的对象,并且随着字符的长度,将完成内存分配。

    【讨论】:

      【解决方案3】:

      在内部,java String 只不过是一个已知长度的 char 数组。以下是String的班级成员:

        110   public final class String
        111       implements java.io.Serializable, Comparable<String>, CharSequence
        112   {
        113       /** The value is used for character storage. */
        114       private final char value[];
        115   
        116       /** The offset is the first index of the storage that is used. */
        117       private final int offset;
        118   
        119       /** The count is the number of characters in the String. */
        120       private final int count;
        121   
        122       /** Cache the hash code for the string */
        123       private int hash; // Default to 0
        124   
        125       /** use serialVersionUID from JDK 1.0.2 for interoperability */
        126       private static final long serialVersionUID = -6849794470754667710L;
                  ...
      

      【讨论】:

        【解决方案4】:

        它像向量一样被动态分配。当它变得太大时,它会通过内部方法(C++)自动调整大小。在 Java 中,正如 thinksteep 已经提到的,字符串是不可变的。

        【讨论】:

          【解决方案5】:

          您将可变尺寸未知尺寸混淆了。任何语言中的具体字符串始终具有已知大小,只是字符串的每个实例可能具有不同的大小。语言处理可变长度的方式可能非常不同,并且是特定于实现的。

          【讨论】:

          • 是的,我将可变大小与未知大小混淆了。原谅我的无知。这种无知在这里导致了一些混乱。我确实是指可变大小,而不是未知大小。
          【解决方案6】:

          只是为了补充以前的答案。
          在 Java 中,字符串可以通过两种方式分配,具体取决于字符串的创建方式。例如,如果字符串是用String s = "some string"; 创建的,JVM 会将这个字符串放入所谓的文字池中(内存问题时留下的东西),如果你用String s = new String("some string"); 创建字符串,JVM 会将它放在堆上... 唯一显着的区别是,如果它们都在文字池中,您可以使用 operator == 来比较字符串,但从不推荐这样做。

          问候

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-22
            • 2016-03-25
            • 2018-06-16
            • 2016-07-01
            • 2021-01-28
            • 1970-01-01
            • 2021-07-27
            • 1970-01-01
            相关资源
            最近更新 更多