【问题标题】:Java Neo4J out of memoryJava Neo4J 内存不足
【发布时间】:2012-06-21 15:18:51
【问题描述】:

这个有点像:Neo4j OutOfMemory problem

但它已经过时了,据我所知,解决方案显然也是如此。

所以我试图插入大约 100K 节点和 5.5M 关系(我实际上削减了我的数据集,所以它现在更像是

过了一会儿,它的内存用完了,我得到一个像这样的异常:

Exception in thread "GC-Monitor" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at java.lang.StringBuilder.toString(Unknown Source)
    at org.neo4j.kernel.impl.util.StringLogger$ActualStringLogger.logMessage(StringLogger.java:276)
    at org.neo4j.kernel.impl.cache.MeasureDoNothing.run(MeasureDoNothing.java:85)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.LinkedList.addBefore(Unknown Source)
    at java.util.LinkedList.add(Unknown Source)
    at org.neo4j.kernel.impl.nioneo.store.IdGeneratorImpl.freeId(IdGeneratorImpl.java:291)
    at org.neo4j.kernel.impl.nioneo.store.CommonAbstractStore.freeId(CommonAbstractStore.java:382)
    at org.neo4j.kernel.impl.nioneo.xa.WriteTransaction.doRollback(WriteTransaction.java:315)
    at org.neo4j.kernel.impl.transaction.xaframework.XaTransaction.rollback(XaTransaction.java:278)
    at org.neo4j.kernel.impl.transaction.xaframework.XaResourceManager.rollback(XaResourceManager.java:518)
    at org.neo4j.kernel.impl.transaction.xaframework.XaResourceHelpImpl.rollback(XaResourceHelpImpl.java:111)
    at org.neo4j.kernel.impl.transaction.TransactionImpl.doRollback(TransactionImpl.java:558)
    at org.neo4j.kernel.impl.transaction.TxManager.rollback(TxManager.java:610)
    at org.neo4j.kernel.impl.transaction.TransactionImpl.rollback(TransactionImpl.java:129)
    at org.neo4j.kernel.TopLevelTransaction.finish(TopLevelTransaction.java:119)
    at sqlToGraph.SqlToGraph.main(SqlToGraph.java:81)

我尝试将 -Xmx1500m 传递给 java,这大约是我可以传递的限制,因为在它抱怨无法分配堆空间之前。它持续的时间明显更长,但仍然没有结束。

这是(稍作编辑的)代码:

/* Postgres query and setup stuff cut */
Transaction tx = graphDb.beginTx();
try {
    while (rs.next()) {
        user_lo = rs.getInt(1);
        user_hi = rs.getInt(2);
        n_lo = getOrCreate(user_lo, graphDb);
        n_lo.setProperty("user_id", user_lo);
        n_lo.setProperty("total", rs.getInt(3));
        n_hi = getOrCreate(user_hi, graphDb);
        n_hi.setProperty("user_id", user_hi);
        n_hi.setProperty("total", rs.getInt(4));
        relationship = n_lo.createRelationshipTo(n_hi, RelTypes.PLAYED_WITH);
        relationship.setProperty("mean_percent", rs.getDouble(5));
    }
    tx.success();
} finally {
    tx.finish();
}
graphDb.shutdown();

【问题讨论】:

  • 如果您获得的是 64 位系统和 JVM,如果您认为无法改进算法以使用更少的内存,可以尝试将堆设置得更大。
  • 您多久提交一次交易?我们可以看看你的代码吗?
  • 不经常?比如,一次?那是我的问题吗?添加代码。
  • 意识到我已经安装了这些东西,我尝试了这个并将堆设置为一个不错的 8gb。它在一夜之间完全停止了我的计算机,我不得不重置:(哦,我也尝试了低于这个的东西,比如 6gb,但是很快就用完了堆。
  • 确实是这个问题。事务数据在提交之前一直保存在内存中。每隔一万左右提交(重启事务)。

标签: java memory neo4j


【解决方案1】:

在此处添加另一个答案。所以给定代码,问题是你永远不会提交你的事务。事务数据在提交之前一直保存在内存中,因此您创建的所有节点和关系都将留在内存中等待提交,这就是您最终获得 OOM 的原因。

我建议更改此代码:

/* Postgres 查询和设置的东西 cut */ 交易 tx = graphDb.beginTx(); 尝试 { for (int i = 0; rs.next(); i++) { user_lo = rs.getInt(1); user_hi = rs.getInt(2); n_lo = getOrCreate(user_lo, graphDb); n_lo.setProperty("user_id", user_lo); n_lo.setProperty("总计", rs.getInt(3)); n_hi = getOrCreate(user_hi, graphDb); n_hi.setProperty("user_id", user_hi); n_hi.setProperty("总计", rs.getInt(4)); 关系 = n_lo.createRelationshipTo(n_hi, RelTypes.PLAYED_WITH); 关系.setProperty("mean_percent", rs.getDouble(5)); // 不时提交以释放内存。 如果 ( 我 > 0 && 我 % 10000 == 0 ) { tx.成功(); tx.finish(); tx = graphDb.beginTx(); } } tx.成功(); } 最后 { tx.finish(); } graphDb.shutdown();

【讨论】:

    【解决方案2】:

    如果拆分事务对您来说不可行,因为您依赖单个事务的原子性保证,另一种选择可能是简化数据模型,例如减少添加到节点/关系的属性数量。

    在我们的例子中,我们可以通过省略保存默认值或零的属性来解决 OOM 问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 2013-09-10
      相关资源
      最近更新 更多