单例模式内存分析

简单说明下:

当在main方法中调用test方法时,test方法会创建一个A类的实例a,同时把实例a的堆区地址放在实例a的成员变量_a中,也就是在模拟成员变量持有指向自身对象引用。

当以上步骤执行完成后,test方法结束,由于a是局部变量,保存在方法栈中,会被立即释放,不再指向A类的实例,但是我们刚刚完成了“自引用”,根据上边的理论,有引用指向A类的实例,实例便不会释放,因此上边程序的输出结果是“main方法指向完毕。。”

遗憾的是,结果并不是这样,真实的输出结果为:“main方法执行完毕。。。A被回收。。。”

为什么会这样?

单例模式创建的对象能够一直存在于内存中不被释放,并不只是由于持有一个自身的引用,本质是因为这个引用是静态,也就是说,如果成员变量是非静态的,它持有一个自身的引用,那么这个对象还是被回收。

"系统内至少保持一个对象的引用",这个引用指的是从栈区或方法区中发出的引用,也就是安全的引用

类被实例化之后,是放在堆区中的,而我们是无法直接操作堆内存的,因此需要一个引用,指向堆区的某个区域,而这个引用,必须是从栈中(或方法区中)发出的,因为我们可以直接访问栈内存,如果是从堆中发出的引用,是无意义的引用,我们根本访问不到,因此会被回收。

类的成员变量恰恰是放在堆内存中,因此由类的成员变量持有一个对象引用,这个引用是不安全的

再举个例子:如果栈区的a局部变量指向堆中的b对象,b对象的某个成员变量指向堆中的c对象。我们可以通过a访问b,再由b访问c,假如一旦a不再指向b,那么再也访问不到b,c也不可能被访问到,即便b此时仍然指向c,但都成了无法访问的对象,b、c均会被jvm自动收回。


单例模式中成员变量是静态的,它并不保存在内存中,而是在方法区中,是一块持久的内存空间,不会被自动回收,因此指向自身的引用是安全的,自身不会被回收。

到此,如果我们把第一个例子中的成员变量改成静态的,那么test方法执行结束后,A类的对象不会被回收,程序输出结果为“main方法执行完毕。。。”


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值