◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
在java中,字符串由于其不变性和实习特性在内存管理中发挥着独特的作用。这些概念不仅可以提高性能,还可以引入内存处理的细微差别,这在面试中通常至关重要。
让我们深入探讨垃圾收集和不变性,并注意字符串池和jvm内存管理如何与这些概念交互。
这篇文章建立在上一篇关于字符串池和内存管理的文章中讨论的概念的基础上。首先查看该文章将为理解此处涵盖的主题提供有用的基础。
在 java 中,字符串文字在垃圾回收 (gc) 方面的行为有所不同。
立即学习“Java免费学习笔记(深入)”;
1。字符串池中未引用的文字
string string3 = "world"; // stored in string pool // a new string is created in the pool due to case-sensitivity string3 = "world";
在此示例中,原始“world”仍在字符串池中,即使 string3 重新分配。
jvm 在池中保留未引用的文字,允许将来重用,但这些文字不会像常规堆对象那样受到垃圾回收。
2。堆对象
string str1 = new string("world"); // stored in heap // string pool reference is used now // leaving the previous "world" eligible for gc in heap str1 = "world";
使用 new 创建时,字符串会进入 堆而不是字符串池。
如果引用发生变化,就像 str1 一样,堆中未使用的“world”字符串可以被垃圾回收,因为它不再被引用。
java 中的字符串不可变——一旦创建,就无法修改。任何“修改”都会产生一个新的字符串对象,而不是更改现有的字符串对象。
1。编译时串联(使用文字优化)
string string5 = "this" + "string";
当串联文字时,java编译器通过在编译时执行串联来优化。
生成的字符串(“thisstring”)直接存储在字符串池中,完全避免了堆。
此过程也称为恒定池折叠。
2。运行时串联(无优化)
string string1 = "hello"; string1 = string1 + "hello"; // stored in heap
当一个或多个操作数是变量(非文字)时,连接发生在运行时,产生一个不驻留在字符串池中的堆对象.
示例:原始“hello”文字保留在池中,而连接的“hellohello”字符串存储在堆中,确认原始“hello”的不变性。
3。使用 concat() 方法
string string2 = "hello"; string2 = string2.concat("hello"); // stored in heap
4。应用 intern() 方法
String string3 = "World".concat(" says Hello").intern();
过程:
首先,concat() 操作在 堆 中创建一个新字符串,其值为“world say hello”,string3 最初引用该字符串。
当我们调用 intern() 时,它会检查该值是否已经在 字符串池 中。如果没有,它将将该值添加到池中并返回对该池实例的引用。
调用 intern() 后,string3 指向字符串的池化副本。原始堆实例现在没有任何活动引用,可以进行垃圾回收,从而减少不必要的内存使用。
通过理解和利用这些原则,java 开发人员可以编写内存效率更高、性能更高的代码。
编码快乐!
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。