【问题标题】:How are arrays of strings stored in memory字符串数组如何存储在内存中
【发布时间】:2014-02-10 22:09:45
【问题描述】:

我正在尝试查看当我有很多重复字符串时使用了多少内存。我正在使用this answer(底部)中突出显示的方法

这是我创建一个包含一千万个字符串的列表,其中每个字符串只有几个字符。

public class Test1 {

    public static void main(String[] args) {
        int count = 10000000;
        List<String> names = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            names.add("test");
        }
        Runtime rt = Runtime.getRuntime();
        long usedMem = rt.totalMemory() - rt.freeMemory();
        System.out.println(usedMem / (1024*1024) + " MB");
    }
}

我运行它,它显示 88 MB。我不太确定这代表什么,但我只是将它作为一个数字来比较。

这是我再次做同样的测试,除了我用一些 lorem ipsum 文本替换了小字符串

public class Test1 {

    public static void main(String[] args) {
        int count = 10000000;
        List<String> names = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            names.add("Lorem ipsum dolor sit amet, brute euismod eleifend te quo, ne qui iudicabit hendrerit. Ea sit dolore assentior prodesset. In ludus adipiscing eos, ius erat graeco at, cu nec melius copiosae. Epicuri suavitate gubergren id sea, possim animal eu nam, cu error libris expetendis his. Te sea agam fabulas, vis eruditi complectitur ei. Ei sale modus vis, pri et iracundia temporibus. Mel mundi antiopam ad.");
        }
        Runtime rt = Runtime.getRuntime();
        long usedMem = rt.totalMemory() - rt.freeMemory();
        System.out.println(usedMem / (1024*1024) + " MB");
    }
}

我运行它,它又说 88 MB。

这并不是要尝试正确地对内存使用进行基准测试,但我预计 ipsum lorem 字符串的数字会更大一些,因为字符串中的字符数大约是 50 倍。

Java 如何在内存中存储字符串数组?或者,我做错了什么?

【问题讨论】:

标签: java


【解决方案1】:

您的 List&lt;String&gt; 没有存储字符串。它存储字符串references

在每种情况下,您都有一个 String 对象,然后是一个包含对同一对象的大量引用的列表。这就像拥有一所房子,以及数百万张带有相同地址的纸。这需要大致相同数量的土地,无论房子是平房还是豪宅。

如果您想查看为列表中要引用的每个条目创建 不同 字符串时会发生什么,请尝试:

for (int i = 0; i < count; i++) {
    names.add("test" + i);
}

现在您将更快地耗尽内存,因为在每次迭代中您将创建一个新的字符串对象,这将占用一定数量的内存。 确切内存量取决于实现,但它通常是一个 String 对象,其中包含对 char[] 对象(字符数组)的引用、起始位置、长度和缓存的哈希码。因此,对于小字符串,文本数据与日常管理工作的开销相比相形见绌,而对于非常大的字符串,char[] 中的数据将占据大部分空间。

【讨论】:

  • 我现在明白了。 lorem ipsum 字符串只有几百个字符的事实在这种情况下并没有产生明显的差异,因为与一千万个引用相比,它仍然只有一个实例。
  • @MxyL:没错。这些引用中的每一个可能只有 4 或 8 个字节,但即便如此,这比单个字符串所需的空间要多得多。
【解决方案2】:

您没有创建 100 万个字符串。您创建了对同一唯一 String 实例的 100 万个引用。字符串文字被实习:每次你的代码使用

String s = "hello";

它使用放置在池中的字符串“hello”。如果 85 个类声明了这样一个变量,那么它们都将引用池中相同的字符串。

如果你真的想要 100 万个 String 实例,那么使用

list.add(new String("..."));

这将制作一个实习字符串的副本,并且您将拥有 100 万个不同的实例。

【讨论】:

    【解决方案3】:

    Java 使用字符串池。这意味着当您多次使用相同的字符串时,它们实际上指向的是同一个实例。

    【讨论】:

      猜你喜欢
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多