java Neo4j:死锁内存泄漏
我有大量的联系人和关系我正试图插入(数以百万计)。为了加快速度,我想我应该批量处理它们,然后让多个线程同时插入它们。这将导致一些死锁,但由于我可以重试,我没有问题
public void doBatch(final Collection<Object> rows) throws Exception {
int retryCount = 3;
while(!(retryCount<3)) {
Transaction tx = graphdb.beginTx();
try {
for (Object row : rows) {
String[] fields = ((String) row).split(DELIMITER, -1);
if (fields.length < 4) {
log.error("Not enough fields to process row:" + row);
} else {
addLineToGraph(fields[0], fields[1], fields[2], fields[3]);
}
}
tx.success();
retryCount = 0;
} catch (DeadlockDetectedException dead) {
tx.failure();
retryCount--;
log.warn("Retry deadlock");
} catch (Exception e) {
tx.failure();
throw e;
} finally {
tx.finish();
}
}
}
不幸的是,经过几个小时的运行和大量死锁后,即使在尝试10G堆之后,我的内存也会耗尽(超出了GC开销限制)。分析堆栈转储后,我注意到很多锁:
One instance of "org.neo4j.kernel.impl.transaction.RWLock" loaded by "sun.misc.Launcher$AppClassLoader @ 0xc0271350" occupies 672.139.928 (84,78%) bytes.
The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "<system class loader>".
我的印象是,这是由于失败的事务没有释放锁造成的,所以我将代码限制为一个线程,以确保不再发生死锁。这样做之后,我可以看到由垃圾收集引起的正常锯齿图,并且不再出现内存不足错误。 根据我对tx.finish()的理解;一切都好吗?还是我遗漏了什么
我在嵌入式模式下使用neo4j 2.0.0-M03
# 1 楼答案
当您更新关系节点的任何属性,然后释放锁时,使用锁怎么样
# 2 楼答案
我升级到2.0.0-M05,现在我有了不同的行为。我得到了PersistenceWindowPool类的空指针。至少目前这个类还不是完全线程安全的。他们告诉我这将在2.0中解决,但在这之前,我将使用我自己的这个类的同步版本
https://github.com/bennies/neo4j/commit/d8a0f4732f347f2038ebace83c14d37d4b1f8691
感谢您提出的所有替代解决方案:)