2012-06-19 3 views
2

Это немного похоже на это: Neo4j OutOfMemory problemJava Neo4j из памяти

Но это устаревшее и, видимо, так это решение, насколько я могу судить.

Так что я пытаюсь вставить около 100 тыс. Узлов с 5.5М отношениями (я фактически сократил свой набор данных, так что теперь он больше похож на < 100K узлов с 2.8M отношениями).

Через некоторое время, он бежит из памяти, и я получаю исключение, как так:

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(); 
+0

Если вы получаете 64-битную систему и JVM, вы можете попробовать увеличить размер кучи, если считаете, что ваш алгоритм не может быть улучшен, чтобы использовать меньше памяти. – AndreiM

+0

Понимая, что я уже установил этот материал, я попробовал это и установил кучу в хороший 8gb. Это полностью остановило мой компьютер за одну ночь, и мне пришлось сбросить: (О, я также попробовал вещи ниже этого, например, 6 ГБ, но быстро выбежал из кучи. –

+0

Спасибо за введенный здесь код, перезагружая транзакцию время от времени, каждый несколько тысяч вставок или около того, решит проблему. –

ответ

10

Добавление другого ответа здесь. Поэтому, учитывая код, проблема заключается в том, что вы никогда не совершаете транзакции. Транзакционные данные хранятся в памяти до тех пор, пока не будут зафиксированы все ваши созданные узлы и отношения будут просто сидеть в памяти, ожидающей фиксации, и именно поэтому вы в конечном итоге получаете OOM.

Я бы предложить это изменение кода:

 
/* Postgres query and setup stuff cut */ 
Transaction tx = graphDb.beginTx(); 
try { 
    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("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)); 

     // Commit every now and then to free memory. 
     if (i > 0 && i % 10000 == 0) { 
      tx.success(); 
      tx.finish(); 
      tx = graphDb.beginTx(); 
     } 
    } 
    tx.success(); 
} finally { 
    tx.finish(); 
} 
graphDb.shutdown(); 
+0

Не только это работало, но и было удивительно ул. Приветствия. –

0

Если раскалывается сделка не представляется возможным для вас, как вы полагаетесь на атомарности гарантии одной транзакции, другой вариант может быть для упрощения модели данных , например уменьшите количество свойств, добавленных в узлы/отношения.

В нашем случае мы могли бы исправить проблему OOM, опуская свойства, которые содержали значения по умолчанию или нули.

Смежные вопросы