spring-data-mongodb 可能发生内存泄漏

Possible memory leak with spring-data-mongodb

我认为 spring-data-mongodb 存在内存泄漏。 基本上,我们使用 MongoDB 作为 RDBMS 的一种缓存,因此当应用程序启动时,我们会加载一大块数据库。 所以基本上我们是 mapping/denormalising 不同的 JPA 实体到 Mongo 文档,使用不同的 "mapping" 方法,比如这个:

    @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 引用,我不知道为什么?

当检查到聚集点的最短路径时,它显示显然是 class

的 earlyApplicationEvents 属性

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

有什么想法吗?

如果您跟踪字段 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 之后获取。