Spring的bean设置成多实例prototype回收问题
来源:2-18 Coding训练:实现AOP注解

大晴子点
2021-03-21
1. 老师,想请教您一个问题,是这样的,我有一个执行器类是作为一个bean的,并且scope是多实例prototype的,然后业务就是每次有文件数据上传时候,它会消费上一个执行器留给它在阻塞队列里的内容。所以只要上传一次新的文件,就要applicationContext.getBean(),获取一个新的对象,然后调用该对象的处理方法。
2. 想问老师的就是,我这里是多实例的,那随着时间推移,系统不重启,不断创建新的对象,内存不是越来越大嘛。。。会自动回收之前创建的对象嘛,但是他又作为一个bean被spring管理,这个生命周期咋样的
3. 还有一个问题就是调用该类处理方法的时候,由于里面需要调用别人系统的接口获取数据,所以我在该类中设置了一个全局map当做缓存,key是当前的this.hashCode(),value就是上面获取的数据,数据量小,不到2000,这样就是为了避免重复掉别人接口耗费时间,再有就是一旦上传了新的文件,this.hashCode会变,这时候正好调别人系统接口获取最新的数据。 有个问题就是我这个全局map会越来越大,应该不会被回收吧,所以想着用redis存30分钟就够了,然后每次从redis取值,但是可能要取个几十万次以上,虽然操作的是redis,但是这样频繁去取,这里需要考虑io,麻烦老师解答下,谢谢
1回答
-
hello你的问题有点长,我其实昨天就看到了。 关于Spring prototype,这种bean很简单,spring创造了, 就不需要跟踪了。 因为每次都是一个新的。 所以如果你prototype bean中有资源,那么就需要实现finalize接口。或者手动释放
接下来,我说说GC的问题……
要不要GC,思考是一方面,但是思考了不能定论。这句话,不是我说的,比我大的大的多的大牛说的。 unix的作者们。会不会出问题,可以假设,但是不能不测试。一定要压测,开jmeter,开30-60min中,打上几千万个请求。 这些就可以帮助你判断要不要GC。
对于单例,Spring会管理。而单例需要回收吗? …… 这个你要思考。
第三个问题:
现在目前系统的架构比较反对你这种设计,因为内存中的状态无法迁移。 除非万不得已, 一般缓存还是走redis这类数据库。 如果一定要本地缓存,建议这种缓存是随时可以丢失的。参考我教你写的LRU,用LRU去存(LRU可以帮助你限制内存大小),这样就有了一个保底的策略。
062021-03-23
相似问题