java中的弱引用和字符串常量池

java中的弱引用和字符串常量池


WeakReference作为java中弱引用的关键字,在执行System.gc();之后,它所指向的对象会被GC回收。先看下面的代码:
public class WeakRef {
        public static void main(String[] args) throws InterruptedException {
            WeakReference r = new WeakReference(new String("I'm here"));
            WeakReference sr = new WeakReference("I'm here nihao");
            System.out.println("before gc: r=" + r.get() + ", static=" + sr.get());
            System.gc();
            Thread.sleep(100);

            // only r.get() becomes null
            System.out.println("after gc: r=" + r.get() + ", static=" + sr.get());

        }
}

上面代码的运行结果是
before gc: r=I’m here, static=I’m here nihao
after gc: r=null, static=I’m here nihao
那么我们很奇怪为什么sr没有被GC回收呢?在参考了Java字符常量池weakreference string didnt garbage collected之后。经过代码测试得到如下的结果:
1 在创建String对象时可以用两种方式

    String s = new String("I am here");
    String ss = "I am here";

2 String s = new String(“I am here”) 创建了几个对象?

答:

2个

解析:

首先,出现了字面量”I am here”,那么去String Pool中查找是否有相同字符串存在,因为程序就这一行代码所以肯定没有,那么就在Java Heap中用字面量”I am here”首先创建1个String对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量s。
接着,new String(“I am here”),关键字new又在Java Heap中创建了1个对象,然后调用接收String参数的构造器进行了初始化。最终s的引用是这个String对象

如上:2个
3

  String abc = new String ("test string pool");
  String abcd = "test string pool";
  boolean flag = abc==abcd;
  System.out.println("compare :"+ flag); 

得到的结果是
compare :false
第一句执行:首先,出现了字面量”test string pool”,那么去String Pool中查找是否有相同字符串存在,因为程序就这一行代码所以肯定没有,那么就在Java Heap中用字面量”test string pool”首先创建1个String对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量s。
字符串常量池中存放的时引用还是对象,这个问题是最常见的。字符串常量池存放的是对象引用,不是对象。在Java中,对象都创建在堆内存中。

接着,new String(“test string pool”),关键字new又在Java Heap中创建了1个对象,然后调用接收String参数的构造器进行了初始化。最终s的引用是这个String对象。
第二句执行:String Pool中查找是否有相同字符串存在,则返回了这个对象的引用给abcd。(这里的对象是第一句执行过程中创建的第一个对象)

下图反应了执行这几句过程中JVM的情况。
jvm内存的情况

再回到开始的问题,r所指向的内存空间,只有r一个变量指向,而sr则有两个变量指向它,一个是sr,一个是string pool中对它引用。所以执行System.gc后,r被回收,而sr指向的内存空间有一个隐形的强引用,不被回收。
第一次写技术博客,有理解不到位的地方大家多多指点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值