前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你担心spring容器中scope为prototype的bean太大内存溢出吗?

你担心spring容器中scope为prototype的bean太大内存溢出吗?

作者头像
stys35
发布2019-03-05 17:41:49
1.1K0
发布2019-03-05 17:41:49
举报
文章被收录于专栏:工作笔记精华

出假设 之前一直担心spring的scope为prototype的bean在一些高并发的场景下,吃不消吗,甚至会内存溢出,这样的担心不是没有道理的,(以下是假设)因为这个类型的bean每一次都会产生新的实例,如果每个实例做一些时间比较长的任务,然后它会在这段时间常驻内存。那么它会爆炸吗?*

猜想1. 非并发的场景下,是正常的。因为它执行完之后在内存回收的时候总是可以被回收的

猜想2.高并发的场景下,会内存溢出。因为在这段执行任务的期间,有多个Bean被初始化了,内存会不断增加。

验证猜想1 下面我们大胆测试以下

测试程序  UserLogic.java

@Component // 保证singleton每次调用userLogic的时候都是最新的userLogic, // 如果没有配合上面的使用,获取这个bean的时候需要根据beanName获取,beanName需要加上前缀scopedTarget // 如getBean(scopedTarget.userLogic) @org.springframework.context.annotation.Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserLogic {     private Long timeMilis;

    private static int _100M = 100 * 1024 * 1024;

    private byte[] memory = new byte[_100M];

    public UserLogic(){         timeMilis = (new Date()).getTime();     }

    public void printTime() {         System.out.println(timeMilis+"");     }

    public Long getTimeMilis() {         return timeMilis;     }

} UserService.java

@Service public class UserService {

    @Autowired     UserLogic logic;

    public void printNowTime(){         logic.printTime();     } } Test.java

//TODO 查看如何创建scope注解的Logic的             service = context.getBean("userService", UserService.class);             logger.debug("===============================first================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);             logger.debug("==============================second================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(3);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5);

            logger.debug("=============================== end ================================");             service.printNowTime();             TimeUnit.SECONDS.sleep(5); 先测试下普通的,非高并发场景下的曲线 

可以看到,被回收掉了,与预想的一样

验证猜想2 现修改UserLogic:::printTime()方法的代码

public void printTime() throws InterruptedException {         Thread.sleep(1000);         System.out.println(timeMilis+"");     } 1 2 3 4 ConcurrentTest.java

 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WuhulalaApplication.class);         //context.start();         final UserService service = context.getBean("userService", UserService.class);         for (int i = 0; i < 20; i++) {             new Thread(() ->{                 try {                     service.printNowTime();                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }).start();         }

        while(true){} 果然报错  Caused by: java.lang.OutOfMemoryError: Java heap space

只不过这些bean执行完任务后立马释放了内存,所以曲线如下图所示[直上直下]

总结 以后使用scope的prototype时候一定要注意。。。。  但是本次测试也只是在极限情况下,比较难发生。。。  但是也是有概率的

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/12/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档