我正在以下面的方式构建MongoClient Connection:
public static synchronized MongoClient getInstance(String mongoDbUri) {
try {
// Standard URI format: mongodb://[dbuser:dbpassword@]host:port/dbname
if( mongoClient == null ){
mongoClient = new MongoClient(
new MongoClientURI(mongoDbUri));
}
} catch (Exception e) {
log.error(
"Error mongo connection : ",
e.getCause());
}
return mongoClient;
}
在运行多个事务的一段时间内,我看到一些内存因应用程序无法释放而消耗殆尽。
分析时,堆转储看到类
时内存消耗最大com.mongodb.internal.connection.PowerOfTwoBufferPool
mongo客户端正在尝试连接到mongos实例。该应用程序在3个分片上有3个副本集,还有一个用于保存元数据的配置服务器。
为了向它添加更多细节,我有一个用@ Component注释的spring托管bean。有一个带@PostConstruct的注释,用于调用上述方法的bean。在spring类中我们正在进行插入/更新/使用Mongo客户端创建。
感谢。
答案 0 :(得分:0)
PowerOfTwoBufferPool 实际上是一个缓存,所以乍一看可能是内存泄漏。
有关详细信息,请参阅 linked reply:
<块引用>...这个 由于 PowerOfTwoBufferPool 是缓存,因此预期行为。因此它 可能看起来像泄漏。
简而言之,PowerOfTwoBufferPool 拥有多个池 ByteBuffer 实例,每个池包含一组相同大小的 缓冲区。最小1K,最大16MB, 从 1K 到 16MB 的两种大小的幂递增。每个的大小 相同大小的缓冲区池不受限制,由 应用程序使用。一旦缓冲区缓存在池中,它就会保持 池(或正在使用)直到 MongoClient 关闭。结果,它是 完全期望在自省 JVM 状态期间,内容 的池将显示为泄漏嫌疑人,就像任何缓存一样。
PowerOfTwoBufferPool 的存在是为了减少 GC 负载。它的 众所周知,JVM 中的现代垃圾收集器处理 大分配与小分配不同,因此如果应用程序 不对大对象(如这些缓冲区)进行任何池化 会有增加GC负载的效果,因为垃圾 收集器必须做比收集这些大对象更多的工作 做较小的。这样做的代价是司机坚持 应用程序的其他部分可以使用的内存。在 特别是,它拥有足够的内存来处理最大的峰值 应用程序目前看到的负载。