Java 调用字符串intern()方法时

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

案例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("equal");//prints equal
  }
后续问题:

  String str = "StackOverFlow";
  String str1 = "StackOverFlow";
  if(str==str1){
      System.out.println("equal");//prints equal
  }
  • 我想知道,对于第一种情况,JVM是否在内部调用
    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”使用的字符串池
    实习生()