spring-data-mongodb可能导致内存泄漏

时间:2017-10-23 09:12:04

标签: mongodb memory-leaks spring-data spring-data-mongodb

我认为我认为是spring-data-mongodb的内存泄漏。 基本上我们将MongoDB用作RDBMS的一种缓存,因此当应用程序启动时,我们加载了一大块数据库。 所以基本上我们使用不同的"映射"将不同的JPA实体映射/非规范化为Mongo文档。像这样的方法:

    @Override
    public void insertFromContacts(Set<Contact> contacts, Long seed){ 
        MutableLong sfId = new MutableLong(seed);

        List<SocialInfo> socialInfos = contacts.stream().map(c -> {
            SocialInfo socialInfo = new SocialInfo();              
            socialInfo.setId(sfId.longValue());
            socialInfo.setSearchOnly(true);
            socialInfo.setStatus(null);
            socialInfo.setContactId(c.getId());
            sfId.increment();
            return socialInfo;
        }).collect(Collectors.toList());

        mongoTemplate.insertAll(socialInfos);
    }

然而内存并没有停止增长,所以我做了堆转储,我意识到spring在内存中保留了大量的BasicDBObject引用,我不知道为什么? java heap dump

当检查到累积点的最短路径时,它显示显然是类的earlyApplicationEvents属性

shortest path to accumulation point

我正在使用:    - Java 8    - Spring数据mongodb 1.10.8.RELEASE    - Spring数据公共1.13.8.RELEASE    - 春季4.3.6.RELEASE

任何想法都是为什么?

1 个答案:

答案 0 :(得分:1)

如果您追踪字段earlyApplicationEvents的使用情况,它基本上是在启动期间保留事件,直到可以注册侦听器,此时它将设置为null。见这里:https://github.com/spring-projects/spring-framework/blob/e7b77cb2b6c699b759a55cd81b345cca00ec5b64/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L828

你提到你在启动时进行处理,所以我想这可以防止在你的过程完成之前注册听众。

如果将该初始化代码进一步移回应用程序上下文完全初始化之后,这应该可以解决问题。例如,注册一个事件监听器并对ContextRefreshedEvent做出反应应该可以解决问题。重要的是在调用刷新过程的registerListeners之后。