GC的字符串实习生

时间:2015-08-09 15:04:26

标签: java string garbage-collection

我读过许多关于字符串实习的文章。

如果我创建一个String对象

方法1

  String str= new String("test")

2在堆中创建一个对象,在字符串池中创建另一个对象。

方法2,如果未执行方法1

  String str= new String("test").intern() 

它将创建一个字符串frpoom堆到字符串池的副本。将创建多少个对象。我猜3.One将在堆中,其他在池中和一个“test”文字。

在这两种情况下哪一个都有资格获得GC。我见过有人说2会被创建,但我无法理解为什么?

方法3

    String s= new String("test")
    String s1=s.intern()

除了s指向堆对象和s1到pool对象之外,它做同样的事情,并且它们都没有资格获得Gc。

我的理解是否正确?我对这个概念感到很困惑。

3 个答案:

答案 0 :(得分:1)

  

如果我创建一个String对象

std::set<CString>
     

在堆中创建对象,在字符串池中创建其他对象。

一个字符串由两个对象组成,std::set<CString, std::less<CString>, std::allocator<CString>>std::less<CString>在某些Java版本中,它可能是ThingComparator或实际上是struct ThingComparator { ... }; template<typename Comparator> static void Blah(std::set<CString, Comparator>& things) { ... } ... std::set<CString, ThingComparator> things; Blah(things); ,后来被替换由 String str= new String("test") 。这意味着可以创建4个,也许可以创建5个对象,除非字符串文字的字符串已经存在,在这种情况下,对于Java 7更新4+,它是2,在此之前,String将被共享,因此它可能是三个对象或只有一个。

char[]

这是完全相同的,除非,如果调用足够的话,可以在堆栈上分配byte[],你可能会发现只创建了char []`,这不能放在堆栈上,此时此刻。将来,这也可能会被优化掉。

  

在这两种情况下哪一个都有资格获得GC。我见过有人说2会被创建,但我无法理解为什么?

答案是1到4,具体取决于具体情况。所有这些都有资格收集,除非它们在某处被强烈引用。

答案 1 :(得分:0)

需要注意的是

  1. String文字自动实习,intern()方法用于使用新String()构建的字符串

  2. Strings(更具体地说,字符串对象)如果变得无法访问,将被垃圾收集,就像任何其他java对象一样。

  3. 字符串literals通常不是垃圾收集的候选者。从Object到该文字将有一个隐式引用。

  4. point#3的原因是如果可以在方法中使用文字来构建String,只要该方法可以执行。

答案 2 :(得分:0)

String intern()方法:

字符串比较最常用的方法是equals()equalsIgnoreCase()方法。但是,对于大字符序列,这些方法可能需要大量内存。 Java String intern()方法帮助我们提高两个字符串之间的比较性能。

intern()方法应用于String对象时,返回对此对象的引用(来自Java所生成的字符串的哈希集),该引用与原始对象具有相同的内容。因此,如果代码对多个String对象使用intern()方法,那么我们的程序将使用更少的内存,因为它将在这些字符串之间的比较中重用对象的引用。

请记住,Java会自动实现字符串文字。这意味着intern()方法将用于使用新String()构造的字符串。

示例:

JavaStringIntern.java

package com.javacodegeeks.javabasics.string; 
public class JavaStringIntern { 
    public static void main(String[] args) { 

        String str1 = "JavaCodeGeeks"; 
        String str2 = "JavaCodeGeeks"; 
        String str3 = "JavaCodeGeeks".intern(); 
        String str4 = new String("JavaCodeGeeks"); 
        String str5 = new String("JavaCodeGeeks").intern(); 
        System.out.println("Are str1 and str2 the same: " + (str1 == str2)); 
        System.out.println("Are str1 and str3 the same: " + (str1 == str3)); 
        System.out.println("Are str1 and str4 the same: " + (str1 == str4)); //this should be "false" because str4 is not interned         
        System.out.println("Are str1 and str4.intern() the same: " + (str1 == str4.intern())); //this should be "true" now                 
        System.out.println("Are str1 and str5 the same: " + (str1 == str5)); 
    } 
} 

Output:
Are str1 and str2 the same: true
Are str1 and str3 the same: true
Are str1 and str4 the same: false
Are str1 and str4.intern() the same: true
Are str1 and str5 the same: true