【发布时间】:2026-01-11 12:55:02
【问题描述】:
不知何故,MongoDB 应用程序最终导致大量 MongoCleanerXXX 线程处于“Timed Waiting”状态,最终导致“OutOfMemory - 无法创建新的本机线程”问题。我正在为 MongoClient 和 dataStore 对象创建一个单例对象,并使用 Morphia 进行 CURD 操作。
我正在使用 Playframework、MongoDB-2.6、mongo-java-driver-2.11.2.jar、morphia-0.99.1-SNAPSHOT.jar
以下是创建数据存储对象的代码。
public enum AppMongoConfig {
INSTANCE;
private MongoClient mongo;
private Morphia morphia = new Morphia();;
private Datastore datastore;
private String ip;
private String schema;
private DB db;
private int port;
private AppMongoConfig() {
initialize();
}
public void initialize() {
Logger.info(" ##### Initializing mongo app db ######");
this.ip = Play.application().configuration()
.getString("appMongoDBHost");
this.schema = Play.application().configuration()
.getString("appMongoDBSchema");
this.port = Play.application().configuration().getInt("appMongoDBPort");
try {
this.mongo = new MongoClient(this.ip, this.port);
} catch (Exception e) {
throw new RuntimeException(e);
}
this.db = this.mongo.getDB(this.schema);
this.datastore = this.morphia.createDatastore(this.mongo,
this.db.getName());
Logger.info(" ##### Initialized mongo app db ######");
}
public Datastore getDs() {
return this.datastore;
}
}
这就是我访问数据库的方式
AppMongoConfig.INSTANCE.getDs()
.find(FileUploadStatusInfo.class).field("pollingId")
.equal(pollingId).get();
我为我的 java 进程使用线程转储来监视线程,我的线程数不断增加,有时会达到 20K。在 20K 中,几乎 19950 个线程是“MongoCleaner”线程。以下是我在 threaddump 中看到的内容。
"MongoCleaner1202732389" daemon prio=10 tid=0x00007f360418a000 nid=0x17c6 waiting on condition [0x00007f35ee2e2000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.mongodb.Mongo$CursorCleanerThread.run(Mongo.java:773)
Locked ownable synchronizers:
- None
"MongoCleaner298435004" daemon prio=10 tid=0x00007f36081a4000 nid=0x17c4 waiting on condition [0x00007f35ee3e3000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.mongodb.Mongo$CursorCleanerThread.run(Mongo.java:773)
Locked ownable synchronizers:
- None
"MongoCleaner1971787750" daemon prio=10 tid=0x00007f36081a2000 nid=0x17c2 waiting on condition [0x00007f35ee4e4000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.mongodb.Mongo$CursorCleanerThread.run(Mongo.java:773)
Locked ownable synchronizers:
- None
这可能是什么原因,作为 MongoDB 的客户端应用程序,我是否做错了什么?
这个问题依然存在,有没有人发现并回答呢。
【问题讨论】:
-
不是一个解决方案,但您是否考虑过升级 Morphia?您的版本很古老(我猜是 3 或 4 年)。不确定调试它是否有意义。
-
是的,我已尝试将其更新为 .102 ,但结果相同。
标签: java mongodb playframework morphia