Neo4j OutOfMemory 问题

Posted

技术标签:

【中文标题】Neo4j OutOfMemory 问题【英文标题】:Neo4j OutOfMemory problem 【发布时间】:2011-02-25 00:29:46 【问题描述】:

这是我的 Main.java 源代码。它是从 neo4j-apoc-1.0 示例中获取的。修改目标为存储2个节点1个关系1M条记录:

package javaapplication2;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;


public class Main

    private static final String DB_PATH = "neo4j-store-1M";
    private static final String NAME_KEY = "name";

    private static enum ExampleRelationshipTypes implements RelationshipType
    
        EXAMPLE
    

    public static void main(String[] args)
    
        GraphDatabaseService graphDb = null;

        try
        
            System.out.println( "Init database..." );


            graphDb = new EmbeddedGraphDatabase( DB_PATH );

            registerShutdownHook( graphDb );


            System.out.println( "Start of creating database..." );


            int valIndex = 0;

            for(int i=0; i<1000; ++i)
            
                for(int j=0; j<1000; ++j)
                
                    Transaction tx = graphDb.beginTx();

                    try
                    
                        Node firstNode = graphDb.createNode();
            firstNode.setProperty( NAME_KEY, "Hello" + valIndex );

                        Node secondNode = graphDb.createNode();
            secondNode.setProperty( NAME_KEY, "World" + valIndex );

                        firstNode.createRelationshipTo(
                           secondNode, ExampleRelationshipTypes.EXAMPLE );

                        tx.success();

                        ++valIndex;
                    
                    finally
                    
                        tx.finish();
                    
                
            

            System.out.println("Ok, client processing finished!");
        
        finally
        
            System.out.println( "Shutting down database ..." );

            graphDb.shutdown();
        
    

    private static void registerShutdownHook( final GraphDatabaseService graphDb )
    
        // Registers a shutdown hook for the Neo4j instance so that it
        // shuts down nicely when the VM exits (even if you "Ctrl-C" the
        // running example before it's completed)
        Runtime.getRuntime().addShutdownHook( new Thread()
        
            @Override
            public void run()
            
                graphDb.shutdown();
            
         );
    

经过几次迭代(大约 150K)后,我收到了错误消息:

"java.lang.OutOfMemoryError: Java 堆空间 在 java.nio.HeapByteBuffer.(HeapByteBuffer.java:39) 在 java.nio.ByteBuffer.allocate(ByteBuffer.java:312) 在 org.neo4j.kernel.impl.nioneo.store.PlainPersistenceWindow.(PlainPersistenceWindow.java:30) 在 org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool.allocateNewWindow(PersistenceWindowPool.java:534) 在 org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool.refreshBricks(PersistenceWindowPool.java:430) 在 org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool.acquire(PersistenceWindowPool.java:122) 在 org.neo4j.kernel.impl.nioneo.store.CommonAbstractStore.acquireWindow(CommonAbstractStore.java:459) 在 org.neo4j.kernel.impl.nioneo.store.AbstractDynamicStore.updateRecord(AbstractDynamicStore.java:240) 在 org.neo4j.kernel.impl.nioneo.store.PropertyStore.updateRecord(PropertyStore.java:209) 在 org.neo4j.kernel.impl.nioneo.xa.Command$PropertyCommand.execute(Command.java:513) 在 org.neo4j.kernel.impl.nioneo.xa.NeoTransaction.doCommit(NeoTransaction.java:443) 在 org.neo4j.kernel.impl.transaction.xaframework.XaTransaction.commit(XaTransaction.java:316) 在 org.neo4j.kernel.impl.transaction.xaframework.XaResourceManager.commit(XaResourceManager.java:399) 在 org.neo4j.kernel.impl.transaction.xaframework.XaResourceHelpImpl.commit(XaResourceHelpImpl.java:64) 在 org.neo4j.kernel.impl.transaction.TransactionImpl.doCommit(TransactionImpl.java:514) 在 org.neo4j.kernel.impl.transaction.TxManager.commit(TxManager.java:571) 在 org.neo4j.kernel.impl.transaction.TxManager.commit(TxManager.java:543) 在 org.neo4j.kernel.impl.transaction.TransactionImpl.commit(TransactionImpl.java:102) 在 org.neo4j.kernel.EmbeddedGraphDbImpl$TransactionImpl.finish(EmbeddedGraphDbImpl.java:329) 在 javaapplication2.Main.main(Main.java:62) 28.05.2010 9:52:14 org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool logWarn 警告:[neo4j-store-1M\neostore.propertystore.db.strings] 无法分配直接缓冲区”

伙计们!帮助我plzzz,我做错了什么,我该如何修复它?在平台 Windows XP 32bit SP3 上测试。也许在创建自定义配置中的解决方案?

thnx 4 每个建议!

【问题讨论】:

首先,将事务移到外循环会大大提高速度。然后是batch inserter。您可以申请一些configuration settings。不过,我不知道在这种情况下是什么导致了错误(但它似乎与 Windows 相关,无法使用 Linux 确认)。 【参考方案1】:

这是 Windows 上的配置问题,其中 Neo4j 无法使用内存映射缓冲区。相反,会在堆上创建一个 Java 缓冲区。在 1.0 中,这个缓冲区默认为 470MB,比 Windows JVM 的默认堆要大。你有两个选择:

    在 pom.xml 中切换到 APOC 1.1-SNAPSHOT 而不是 1.0,它具有自动配置,将最多 50% 的可用 JVM 堆分配给 Neo4j

    通过运行 Java 将 JVM 堆调整为更多(例如 512Mb)

    java -Xmx512m ....

    您甚至可以在 Eclipse 的运行配置中的 JVM 参数下插入它

如果这有帮助,请告诉我们!

此外,为每个节点对执行完整事务将需要很长时间。尝试在第一个循环中打开一个事务并仅每 1000 个节点对提交一次?

/彼得

【讨论】:

APOC 1.1-SNAPSHOT 下载位于here,如果您不使用 Maven(那么只需更新您的 pom.xml)。 太棒了!我尝试了 -Xmx512m 参数,现在它工作正常 4;)谢谢! 很好,很高兴能够提供帮助!

以上是关于Neo4j OutOfMemory 问题的主要内容,如果未能解决你的问题,请参考以下文章

内存泄漏和内存溢出的区别

内存溢出和内存泄漏的区别,产生原因以及解决方案

Delphi疑难杂症之:Outof system resources

outofmemory怎么修复

Android:OutOfMemory 错误和后台堆栈

OutOfMemory相关问题(内存溢出异常OOM)