我正在使用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引用,我不知道为什么?
检查到累积点的最短路径时,它显示该类显然是earlyApplicationEvents属性
我正在使用: - Java 8 - Spring数据mongodb 1.10.8.RELEASE - Spring数据公共1.13.8.RELEASE - Spring 4.3.6.RELEASE
任何想法为什么?
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之后获取刷新过程 .