对于java程序中的字符直接量,JVM会使用一个字串池来保存它们。当第一次使用某个字符串直接量时,JVM会将它放入字符串池中进行缓存。在一般情况下,字符串池中的字符串对象不会被垃圾回收。当程序再次需要使用该字符串时,无需重新创建一个新的字符串就可以直接让引用变量直接指向字符串中已有的字符串。而使用new操作创建的字符串对象不指向字符串池中的对象,但是可以使用intern方法使其指向字符串池中的对象。
public class StringDemo {
public static void main(String args[]){
String str1 = "abc";
String str2 = "abc";
String str3 = "def";
String str4 = "abcdef";
String str5 = "abc" + "def";//在字符串池中能找到“abcdef”对象,故str5 == str4 为true
String str6 = str2 + str3;//在运行时才知道,也就是说str1+str2是在堆里创建的
String str7 = new String("abcdef");//new操作创建的字符串对象不指向字符串池中的对象
String str8 = str7.intern();//使用intern方法使str7指向的对象加入字符串池中
if(str1 == str2){
System.out.println("此时str1引用变量与str2引用变量" +
"是指向在字符串池中的同一个内存块");
}else{
System.out.println("此时str1引用变量与str2引用变量" +
"不是指向在字符串池中的同一个内存块");
}
if(str4 == str5){
System.out.println("此时str4引用变量与str5引用变量" +
"是指向在字符串池中的同一个内存块");
}else{
System.out.println("此时str4引用变量与str5引用变量" +
"不是指向在字符串池中的同一个内存块");
}
if(str4 == str6){
System.out.println("此时str4引用变量与str6引用变量" +
"是指向在字符串池中的同一个内存块");
}else{
System.out.println("此时str4引用变量与str6引用变量" +
"不是指向在字符串池中的同一个内存块");
}
if(str4 == str7){
System.out.println("此时str4引用变量与str7引用变量" +
"是指向在字符串池中的同一个内存块");
}else{
System.out.println("此时str4引用变量与str7引用变量" +
"不是指向在字符串池中的同一个内存块");
}
if(str4 == str8){
System.out.println("此时str4引用变量与str8引用变量" +
"是指向在字符串池中的同一个内存块");
}else{
System.out.println("此时str4引用变量与str8引用变量" +
"不是指向在字符串池中的同一个内存块");
}
}
}
/*out:
此时str1引用变量与str2引用变量是指向在字符串池中的同一个内存块
此时str4引用变量与str5引用变量是指向在字符串池中的同一个内存块
此时str4引用变量与str6引用变量不是指向在字符串池中的同一个内存块
此时str4引用变量与str7引用变量不是指向在字符串池中的同一个内存块
此时str4引用变量与str8引用变量是指向在字符串池中的同一个内存块*/
因为字符串池中的字符串对象不会被垃圾回收,所以当某个字符串池中的字符串对象失去引用时,它将变成垃圾,而字符串池又不回收。于是便产生了java内存泄露。示例如下:
public class StringDemo1 {
public static void main(String args[]){
String str1 = "abc";
String str3 = "def";
str3 = str1 ;
System.out.println(str3);
System.out.println(str1);
}
}
/*out:
abc
abc
*/
/*"def"失去引用,将成为垃圾,进而内存泄露*/
分享到:
相关推荐
字符串池的主要目的是减少内存中的重复字符串实例,当创建一个新字符串时,.NET会首先检查字符串池中是否存在相同的字符串,如果存在,则直接返回池中的引用,而不是创建新的实例。这样避免了大量的内存分配和垃圾...
Java字符串池和字符对象是Java编程中的重要概念,主要涉及到String类的特性和内存管理。在Java中,String是一个不可变类,这意味着一旦创建了一个String对象,它的值就不能被修改。这种不变性使得String对象在多线程...
第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: ...
字符串的`intern()`方法会将字符串对象加入到字符串池中,如果字符串池中已有相同的字符串,则返回池中的引用。 10. **编码与解码**: 字符串与字节之间的转换涉及到编码问题,如`getBytes()`和`new String(byte...
这种机制称为字符串池的“复用”。 ### 字面量创建与`new`创建的区别 1. **字面量创建**:例如`String str1 = "hello"`。这种方式创建的字符串会直接或间接地进入字符串常量池。如果多次声明相同的字面量,JVM只会...
"Java 字符串池的深入理解" Java 字符串池是 Java 中的一种特性,旨在提高内存利用率。字符串池的工作机制是,当我们使用双引号声明一个字符串时,Java 会先在字符串池中寻找是否已经存在该字符串,如果没有,则...
当创建一个新的字符串时,如果字符串池中已经存在相同的字符串,则不会创建新的对象,而是直接引用已存在的字符串。 ```java String s1 = "abcd"; String s2 = "abcd"; // s1 和 s2 指向的是同一个对象 ``` ##...
7. **字符串池**:C#有内置的字符串池,可以优化短字符串的创建和销毁。但对长字符串或大量字符串,可能需要手动管理。 总结,生成和比较大量字符串涉及到字符串生成技巧、比较方法选择、性能优化策略以及内存管理...
7. **性能优化**:针对特定场景,可以优化字符串的内存管理,例如预分配空间以减少动态内存分配,或者使用字符串池来减少内存碎片。 8. **错误处理**:在封装过程中,应考虑异常安全性和错误处理,比如当操作失败时...
对于第二种方式,Java虚拟机(JVM)会在字符串池中检查是否已有相同值的`String`对象。如果有,就直接引用;如果没有,才会在堆中创建新对象并放入字符串池。 【字符串池】 字符串池是一种内存区域,存储了已创建的...
10. **字符串优化**:在处理大量字符串时,了解内存管理(如Python的字符串连接优化)和字符串池的概念能提高程序效率。 这些只是字符串处理的一部分基础概念,实际的"字符串习题总结"可能会涵盖更高级的主题,如...
10. **String对象的池化**:Java 1.5引入了字符串池,用于优化性能。字符串字面量和`String.intern()`方法都涉及到字符串池的概念。 本压缩包的“Chapter15”可能涵盖了以上部分或全部知识点,包括实例演示、上机...
同时,合理使用字符串池和内存分配策略可以提升程序效率。 总的来说,理解和熟练掌握字符串处理函数是每个程序员的基本功,无论是进行数据解析、日志记录,还是构建复杂的文本算法,这些函数都起着关键作用。通过...
字符串常量存储在字符串池中,通过`""`创建的字符串会被自动加入到池中。 **5.2.6 正则表达式** Java支持正则表达式,可以使用`Pattern`和`Matcher`类进行匹配、替换和查找操作。 总结,数组和字符串是Java编程的...
因此,合理使用字符串操作和内存管理技巧(如字符串池、引用计数等)对提高程序效率至关重要。 总的来说,字符串是编程中的基本元素,理解和掌握其特性和操作方法对于任何程序员来说都是必要的。通过深入学习和实践...
8. **字符串效率**:讨论如何优化字符串操作,例如避免不必要的拷贝,使用字符串池等。 9. **错误处理**:在实现字符串处理函数时,需要考虑边界条件、空字符串、越界访问等问题,并编写适当的错误处理代码。 10. ...
例如,`String s = new String("we are students")` 创建了一个新的`String`对象,而 `String s2 = "we are students"` 直接引用了字符串池中的对象。此外,还可以使用字符数组或其子序列创建字符串。 2. **引用...