Mongo Java Connection导致内存泄漏

时间:2015-06-16 11:48:46

标签: java mongodb memory-leaks

我正在以下面的方式构建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客户端创建。

感谢。

1 个答案:

答案 0 :(得分:0)

PowerOfTwoBufferPool 实际上是一个缓存,所以乍一看可能是内存泄漏。

有关详细信息,请参阅 linked reply

<块引用>

...这个 由于 PowerOfTwoBufferPool 是缓存,因此预期行为。因此它 可能看起来像泄漏。

简而言之,PowerOfTwoBufferPool 拥有多个池 ByteBuffer 实例,每个池包含一组相同大小的 缓冲区。最小1K,最大16MB, 从 1K 到 16MB 的两种大小的幂递增。每个的大小 相同大小的缓冲区池不受限制,由 应用程序使用。一旦缓冲区缓存在池中,它就会保持 池(或正在使用)直到 MongoClient 关闭。结果,它是 完全期望在自省 JVM 状态期间,内容 的池将显示为泄漏嫌疑人,就像任何缓存一样。

PowerOfTwoBufferPool 的存在是为了减少 GC 负载。它的 众所周知,JVM 中的现代垃圾收集器处理 大分配与小分配不同,因此如果应用程序 不对大对象(如这些缓冲区)进行任何池化 会有增加GC负载的效果,因为垃圾 收集器必须做比收集这些大对象更多的工作 做较小的。这样做的代价是司机坚持 应用程序的其他部分可以使用的内存。在 特别是,它拥有足够的内存来处理最大的峰值 应用程序目前看到的负载。