美文网首页
java intern

java intern

作者: 币来币往 | 来源:发表于2019-03-10 14:02 被阅读0次

    JDK7 中将StringPool从永久代移动到了老生代,并且可以通过-XX:StringTableSize=99991来改变常量池的大小。

    public void equalTest(){
           String s = new String("1").intern();
           String s2 = "1";
           System.out.println(s2 == s);
       }
    output: true
    
    public void equalTest(){
           String s = new String("1");
           s.intern();
           String s2 = "1";
           System.out.println(s2 == s);
       }
    output: false
    

    jdk7下面第一段代码打印的是true,第二段打印的是false.
    这是因为将常量池从永久的移动到老生代之后,intern()的意思是将该变量放到常量池中,因为new String("1")已经是在堆中了,所以会直接将其引用放入常量池中,这样当s2="1"语句直接去常量池中查找对象时得到的其实就是s所指向的对象。
    第二段代码中,new String("1); 会生成两个对象一个是s指向的Object String,一个是常量池中的对象; 然后执行s.intern()的时候发现常量池中已经有该对象了,所以什么也不做。s2则指向常量池中的对象。因此s != s2

    我们再来看下面这段代码:

    public static void main(String[] args){
            int length = 100000000;
            String[] s = new String[length];
            int i = 0;
            while(i < length){
                s[i++] = new String("hellosdfasfsdddddddddddddd").intern();
            }
        }
    

    new String("hellosdfasfsdddddddddddddd").intern() 这句话的意思是在常量池中new一个对象,所以当我们第一次执行常量池中有了这个对象之后,后面就不会再new新对象了,大大节约了内存空间。
    下面是有intern和没有intern的堆内存使用情况,大家感受一下

    s[i++] = new String("hellosdfasfsdddddddddddddd").intern();
    
    PS Old Generation
       capacity = 1431830528 (1365.5MB)
       used     = 400008208 (381.47755432128906MB)
       free     = 1031822320 (984.0224456787109MB)
       27.936840301815383% used
    
    s[i++] = new String("hellosdfasfsdddddddddddddd");
    
    PS Old Generation
       capacity = 1431830528 (1365.5MB)
       used     = 1431412656 (1365.1014862060547MB)
       free     = 417872 (0.3985137939453125MB)
       99.97081554053861% used
    

    相关文章

      网友评论

          本文标题:java intern

          本文链接:https://www.haomeiwen.com/subject/njmupqtx.html