修改后的 DeepLearning4Java(使用 akka)的内存泄漏或拥挤的工作人员
Memory Leak or Congested Workers with modified DeepLearning4Java (using akka)
我正在使用 DeepLearning4Java 的修改版本来处理使用 UIMA CollectionReader 的文档。对于大型文档集合,我 运行 陷入 GC 开销限制错误或不同类型的超时错误(例如线程 "RMI TCP Connection(idle)" 中的异常),因为垃圾收集花费了更多时间。我不确定这是内存泄漏还是我只是在工作人员邮箱中堆积了太多工作。我不熟悉没有帮助的 scala 和 akka。
发生的情况是,我的应用程序 运行 在接近堆限制(尝试使用 4GB 和 8GB)之前一直很好,在达到 GC 开销限制之前速度变慢。这不是 PermGen space 使用量永远不会超过 45 MB 的问题,也不是创建太多 类 的问题 - 我只看到加载了大约 7000 个,并且它基本上完全平坦 运行时间。
可以在下面的屏幕截图中看到罪魁祸首。
这些对象在 org.deeplearning4j.bagofwords.vectorizer.BaseTextVectorizer 中实例化为 vocabActor.tell。
while(docIter != null && docIter.hasNext()) {
vocabActor.tell(new StreamWork(new DefaultInputStreamCreator(docIter),latch),vocabActor);
queued.incrementAndGet();
if(queued.get() % 10000 == 0) {
log.info("Sent " + queued);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
我理解的tell函数是akka中的scala代码
final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender)
我的理解是,这会进入工作人员的邮箱等待处理 - 但我假设一旦处理完工作,所有对此的引用都会消失。所以我不确定为什么有这么多对象持久存在,一定有一些钩子阻止 GC 丢弃这些对象——也许是因为它们在邮箱中并且尚未处理?循环可以 运行 一段时间,但我假设所有 StreamWork 对象都被回收了。
我的问题是是否有办法确定我是否需要切换到不同类型的调度程序以某种方式限制消息生成,或者我是否应该调查内存泄漏。如果需要,我可以 post DocumentIterator 或其他代码。
请始终使用 Maven Central 提供的最新 dl4j/nd4j 版本。
你说的BUG已经修复了一段时间了,现在Akka已经不用了。
p.s。目前最新版本为0.4-rc3.8
我正在使用 DeepLearning4Java 的修改版本来处理使用 UIMA CollectionReader 的文档。对于大型文档集合,我 运行 陷入 GC 开销限制错误或不同类型的超时错误(例如线程 "RMI TCP Connection(idle)" 中的异常),因为垃圾收集花费了更多时间。我不确定这是内存泄漏还是我只是在工作人员邮箱中堆积了太多工作。我不熟悉没有帮助的 scala 和 akka。
发生的情况是,我的应用程序 运行 在接近堆限制(尝试使用 4GB 和 8GB)之前一直很好,在达到 GC 开销限制之前速度变慢。这不是 PermGen space 使用量永远不会超过 45 MB 的问题,也不是创建太多 类 的问题 - 我只看到加载了大约 7000 个,并且它基本上完全平坦 运行时间。
可以在下面的屏幕截图中看到罪魁祸首。
这些对象在 org.deeplearning4j.bagofwords.vectorizer.BaseTextVectorizer 中实例化为 vocabActor.tell。
while(docIter != null && docIter.hasNext()) {
vocabActor.tell(new StreamWork(new DefaultInputStreamCreator(docIter),latch),vocabActor);
queued.incrementAndGet();
if(queued.get() % 10000 == 0) {
log.info("Sent " + queued);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
我理解的tell函数是akka中的scala代码
final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender)
我的理解是,这会进入工作人员的邮箱等待处理 - 但我假设一旦处理完工作,所有对此的引用都会消失。所以我不确定为什么有这么多对象持久存在,一定有一些钩子阻止 GC 丢弃这些对象——也许是因为它们在邮箱中并且尚未处理?循环可以 运行 一段时间,但我假设所有 StreamWork 对象都被回收了。
我的问题是是否有办法确定我是否需要切换到不同类型的调度程序以某种方式限制消息生成,或者我是否应该调查内存泄漏。如果需要,我可以 post DocumentIterator 或其他代码。
请始终使用 Maven Central 提供的最新 dl4j/nd4j 版本。 你说的BUG已经修复了一段时间了,现在Akka已经不用了。
p.s。目前最新版本为0.4-rc3.8