Java 调用字符串intern()方法时
案例1:Java 调用字符串intern()方法时,java,string,memory-management,Java,String,Memory Management,案例1: String str = "StackOverFlow"; String str1 = "StackOverFlow"; if(str==str1){ System.out.println("equal");//prints equal } 案例2: String str = "StackOverFlow"; String str1=str.intern(); if(str==str1){ System.out.println("e
String str = "StackOverFlow";
String str1 = "StackOverFlow";
if(str==str1){
System.out.println("equal");//prints equal
}
案例2:
String str = "StackOverFlow";
String str1=str.intern();
if(str==str1){
System.out.println("equal");//prints equal
}
后续问题:
String str = "StackOverFlow";
String str1 = "StackOverFlow";
if(str==str1){
System.out.println("equal");//prints equal
}
intern()
,并将str
的引用分配给str1
string str=“StackOverFlow”
它添加到字符串池中,与intern()
方法相同String str=“StackOverFlow”使用的字符串池代码>和intern()
是在堆外分配的吗?如果是,具体在哪里
问题4的答案如下: 在Java 6和更早版本中,插入的字符串也存储在永久生成中。在Java 7中,插入的字符串存储在主对象堆中。 以下是文档说明:
String str = "StackOverFlow";
String str1 = "StackOverFlow";
if(str==str1){
System.out.println("equal");//prints equal
}
在JDK 7中,不再在永久数据库中分配内部字符串
生成Java堆,但在主
Java堆的一部分(称为年轻一代和老一代),以及
使用应用程序创建的其他对象。这一变化将
导致更多的数据驻留在主Java堆中,而更少的数据驻留在主Java堆中
永久性生成,因此可能需要
调整。大多数应用程序只会看到相对较小的差异
由于此更改,堆使用率降低,但更大的应用程序
许多类或函数大量使用String.intern()
方法将看到
更显著的差异
详情如下:
Java 6中的String.intern()
在那些美好的过去,所有被拘留的字符串都存储在PermGen中
–堆的固定大小部分,主要用于存储加载的类
和串池。除了显式插入字符串外,PermGen字符串
池还包含程序中先前使用的所有文本字符串
(这里使用的是一个重要的词——如果从未使用过类或方法
已加载/调用,将不会加载其中定义的任何常量)
运行时。您可以使用-XX:MaxPermSize=96m选项进行设置。据我所知
要知道,默认的永久发电机大小在32M和96M之间变化,具体取决于
站台。您可以增加其大小,但其大小仍将保持不变
固定的这种限制要求非常小心地使用String.intern——
你最好不要用这种方法实习任何不受控制的用户输入。
这就是为什么Java 6时代的字符串池主要在
手动管理的地图
Java 7中的String.intern()
Oracle工程师对字符串进行了极其重要的更改
Java 7中的池逻辑–字符串池被重新定位到堆中。
这意味着您不再受单独的固定大小的限制
内存区。所有字符串现在都位于堆中,就像大多数其他字符串一样
普通对象,它允许您在
调整应用程序。从技术上讲,仅此一项就足够了
重新考虑在Java 7程序中使用String.intern()的原因。
但还有其他原因
引用是相等的,因为它们都是字符串文字 不需要对
str
调用intern()
,因为它也是一个文本。您需要使用intern()
(顺便说一句,它比equals()
慢得多,所以不要使用它)的示例是使用字节或字符数组构造字符串
例如:
final String str1 = "I am a literal";
final String str2 = new String(str1.toCharArray());
final boolean check1 = str1 == str2; // false
final boolean check2 = str1 == str2.intern(); // true
引用是相等的,因为它们都是字符串文字 不需要对
str
调用intern()
,因为它也是一个文本。您需要使用intern()
(顺便说一句,它比equals()
慢得多,所以不要使用它)的示例是使用字节或字符数组构造字符串
例如:
final String str1 = "I am a literal";
final String str2 = new String(str1.toCharArray());
final boolean check1 = str1 == str2; // false
final boolean check2 = str1 == str2.intern(); // true
创建字符串对象主要有两种方法 一是
String str = "test-String"; // This string is created in string pool or returned from
string pool if already exists
第二个
String str = new String("test-string");// This string object will be created in heap memory and will be treated as any other object
在使用新运算符创建的字符串实例上调用string.intern时。。。此字符串将在字符串池中创建或从该池返回(如果存在)。这是一种将字符串对象从堆移动到perm Gen(字符串池)的机制。创建字符串对象的方法主要有两种 一是
String str = "test-String"; // This string is created in string pool or returned from
string pool if already exists
第二个
String str = new String("test-string");// This string object will be created in heap memory and will be treated as any other object
在使用新运算符创建的字符串实例上调用string.intern时。。。此字符串将在字符串池中创建或从该池返回(如果存在)。这是一种将字符串对象从heap移动到perm Gen(字符串池)的机制
1) 我想知道,对于第一种情况,JVM是否在内部调用intern(),并将str的引用分配给str1
嗯,是和否
是,内部调用intern()
方法。但是当代码运行时,调用不会发生。事实上,它发生在加载代码时。然后,加载器保存对插入字符串的引用
但在这种情况下,加载过程只需要进行一次实习。这两个文本(在本例中)实际上由正在加载的类中的单个“常量池条目”表示。(Java编译器将在编译时发现类中的重复文本,并将其删除。)
2) 在第一种情况下,两个引用如何相等
因为这两条线已经被拘留了
3) 第一种情况是否意味着每当您声明类似string str=“StackOverFlow”的字符串时;它与intern()方法一样添加到字符串池中
是的。。。当包含声明的代码运行时,不发生插入
4) 不存在由String str=“StackOverFlow”使用的字符串池代码>和实习生()