Spring管理单例对象的时候,如何实现不被JVM回收的?

售前免费咨询热线: 4 0 0 - 1 8 6 - 0 9 0 5
汇智资讯Huizhi information

当前位置:首页 »Spring管理单例对象的时候,如何实现不被JVM回收的?

Spring管理单例对象的时候,如何实现不被JVM回收的?

日期:2020-11-24 16:37:19 访问量: 来源:

这个问题肯定要分为JVM对象回收和Spring对象管理来说的!如果看完还不会,你尽管来抽我。。

一,JVM对象回收:

就是对没有引用存在的对象进行回收,最原始的做法是加一个对象引用计数器,比如A被B引用了,则A对象的引用计数器为1,只要B没被回收,A的引用计数大于0,A就不会被回收!

但是这样做是有隐患的,如果A引用B,B引用A,然后没有任何其他对象引用A,B的时候,理论上AB都应该被回收了,但是AB引用计数器上面的计数都为1,不能回收,这样两个永远不会使用但也无法回收的对象占据着内存,直到内存溢出!

Spring管理

JVM是怎么解决这一现象的呢?引入一个GCRoots(引用链)的东西,把静态对象引用,常量引用等作为根节点,其余所有的引用都挂在这棵引用树上,上面说到的AB,如果从根节点上遍历的时候没有找到AB的引用(不可达根节点),就说明AB已经脱离了引用链,就算引用计数器还为1,也将被回收!

二,spring管理对象:

首先我们要知道spring通过IOC控制反转帮助开发者管理对象,在spring容器启动的时候加载类(所有实现了BeanFactory的类),然后实例化对象(这儿不讨论是否懒加载等),最后进行使用!

如下图,就是创建对象的父接口:

Spring管理

先看SimpleJndiBeanFactory类:

Spring管理

Spring管理

在SimpleJndiBeanFactory类中,先new了一个名叫singletonObjects的final修饰的hashmap变量,在容器启动的时候,通过doGetSingleton方法把jndi反射得到的实例化对象放入此hashMap中,作为new出来的强引用,没有进行释放就会一直挂在引用链上,不会进行释放!

再看看ApplicationContext下面的StaticListableBeanFactory类,使用new出来的名为beans的LinkedHashMap进行管理,同时使用addBean方法加入对象到map中,方便及时调用!

Spring管理
Spring管理

综上,spring管理的对象,都通过map等形式加载,挂在了引用链上,所以并不会一不使用就被回收了!

汇聚行业精英智慧

致力于高端IT技术人才培养

助力万千学员成就IT梦!

汇智动力

扫码关注 领取资料

www.hzdledu.cn

相关阅读Reading

全国热线:400-186-0905

总部热线:028-6547-1147

周一至周日9:30-24:00

我要咨询
汇智动力微信

汇智动力微信公众号