【问题标题】:Java String Immutability storage when String object is changed更改 String 对象时的 Java String Immutability 存储
【发布时间】:2023-03-06 11:58:01
【问题描述】:

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

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

例如

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

那么如果写下一条语句如下。

s = "value2";

所以我的问题是,

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

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

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

在分配字面量后会立即从堆中释放空间吗?

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

【问题讨论】:

  • 您问题的关键是 - s 不是对象。它是对对象的引用。您确实更改了引用,但您没有更改此处的任何对象。
  • 还要注意,String 对象是不可变的。因此,您无法更新字符串对象的值(直接。反射可用于破坏不变性)。在您的特定情况下,只要s 重新分配,堆上的字符串“value1”就有资格进行 GC。当加载定义此文字的类的类加载器被 GC 时,字符串文字“Value1”将有资格进行 GC。
  • @DmitryZaitsev 但是根据我读到的参考资料,如果它是用新的关键字初始化的,它将在堆空间中创建一个对象。所以有一个空间被物体占据。那么当分配一个文字(不在堆空间中)时,该空间会发生什么。
  • 我指的是存储在s 中的那个(通过new 运算符显式创建的那个)。

标签: java oop heap-memory immutability string-pool


【解决方案1】:

修改Strings

运行时值不更新

s = "value2";

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

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

垃圾回收

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

默认情况下new String(...) 对象没有被实习,因此垃圾回收的正常规则适用。这些只是普通的对象。

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

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


回答您的其他问题:

在分配字面量后,它会立即从堆中释放空间吗?

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

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

你的第一个字符串:

String s = new String("Value1");

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

现在如果你打电话:

s = "value2";

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

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

【讨论】:

    【解决方案2】:

    如果您需要更改一个字符串,您可以随时创建一个包含 修改。

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

    【讨论】:

    • 我认为这应该是评论,而不是答案。我不会 dv,但我想有些人会:s.
    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2012-06-22
    • 2015-08-30
    • 2017-10-29
    相关资源
    最近更新 更多