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吗?
谁能解释一下从第一个语句到第二个语句的值是什么,以及内存区域(堆和字符串池)会发生什么。
正在修改 String
s
当运行
时值未更新
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,它允许更改字符串。
我了解到,如果一个字符串是用文字初始化的,那么它会在字符串池中分配一个 space,如果用新的关键字初始化,它会创建一个字符串的对象。但是我对下面写的一个案例感到困惑。
我的问题是,如果使用 new 关键字创建一个字符串,然后使用文字更新它的值怎么办?
例如
String s = new String("Value1"); -- Creates a new object in heap space
那如果把下一条语句写成下面这样呢
s = "value2";
所以我的问题是,
1 它会在字符串池中创建一个字符串文字还是会更新该对象的值?
2 如果它在字符串池中创建一个新文字,当前存在的对象会发生什么?它会被销毁还是会一直存在直到调用垃圾收集器。
这是一个小字符串,如果字符串是数千个字符,那么我只是担心它使用的space。所以我的关键问题是 space.
分配文字后会立即从堆中释放space吗?
谁能解释一下从第一个语句到第二个语句的值是什么,以及内存区域(堆和字符串池)会发生什么。
正在修改 String
s
当运行
时值未更新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,它允许更改字符串。