Java String 对象改变时的 String Immutability 存储

Java String Immutability storage when String object is changed

我了解到,如果一个字符串是用文字初始化的,那么它会在字符串池中分配一个 space,如果用新的关键字初始化,它会创建一个字符串的对象。但是我对下面写的一个案例感到困惑。

我的问题是,如果使用 new 关键字创建一个字符串,然后使用文字更新它的值怎么办?

例如

String s = new String("Value1");  -- Creates a new object in heap space

那如果把下一条语句写成下面这样呢

s = "value2";

所以我的问题是,

1 它会在字符串池中创建一个字符串文字还是会更新该对象的值?

2 如果它在字符串池中创建一个新文字,当前存在的对象会发生什么?它会被销毁还是会一直存在直到调用垃圾收集器。

这是一个小字符串,如果字符串是数千个字符,那么我只是担心它使用的space。所以我的关键问题是 space.

分配文字后会立即从堆中释放space吗?

谁能解释一下从第一个语句到第二个语句的值是什么,以及内存区域(堆和字符串池)会发生什么。

正在修改 Strings

当运行

值未更新
s = "value2";

在Java中,除了基本类型外,所有其他变量都是对对象的引用。这意味着只有 s 指向新值。

不变性保证对象的状态在构造后不能改变。换句话说,无法修改 Java 中任何 String 对象的内容。例如,如果你声明 s = s+"a"; 你已经创建了一个 new 字符串,它以某种方式存储了新文本。

垃圾收集

This answer 已经提供了深入的答案。如果您不想阅读完整答案,请在下面进行简短摘要,但它省略了一些细节。

默认情况下 new String(...) 对象不会被驻留,因此垃圾收集的正常规则适用。这些只是普通的物品。

代码中驻留的常量字符串通常不会被删除,因为最终您可能会引用这些字符串。

然而,答案中有一个旁注,有时 类 是动态(卸载)加载的,在这种情况下,可以从池中删除文字。


回答您的其他问题:

Will it immediately free the space from the heap after assigning the literal?

,那不是很有效:垃圾收集器需要分析要删除哪些对象。您可能与其他对象共享了对旧字符串的引用,因此不能保证您可以回收该对象。此外,存储不再有用的数据并没有太大问题,只要您不需要向操作系统请求额外的内存(将其与您的计算机进行比较,只要您可以将所有数据存储在硬盘驱动器上即可,您真的不必担心无用的文件,从您必须购买额外驱动器的那一刻起,您可能会先尝试删除一些文件)。分析需要一些计算工作。通常,垃圾收集器仅在(几乎)耗尽内存时运行。所以你不应该太担心内存。

Can anyone explain what what value goes where from the first statement to the second and what will happened to the memory area (heap and String Pool).

你的第一个字符串:

String s = new String("Value1");

是对堆的引用。如果调用该命令,它将在堆上为字符串分配 space。

现在如果你打电话:

s = "value2";

"value2" 字符串池 的一个元素,它将保留在那里直到您的程序结束。

因为您不再有对旧字符串 (value1) 的引用。该对象是收集的候选对象。如果垃圾收集器 稍后 走过,它将从堆中删除对象并将 space 标记为空闲。

If you need to change a string, you can always create a new one that contains the modifications.

  • Java 定义了 String 的对等 class,称为 StringBuffer,它允许更改字符串。