Neo4j Java API:运行多个查询后超出了GC开销限制

Neo4j Java API:运行多个查询后超出了GC开销限制,java,neo4j,garbage-collection,graph-databases,Java,Neo4j,Garbage Collection,Graph Databases,我正在Java中使用Neo4j 2.3.0。我有16 GB的RAM,在MacOSX笔记本电脑上运行代码,使用“-Xmx12g-Xms12g”作为VM参数 我在Neo4JJavaAPI中遇到了“超出GC开销限制”的问题 为了对大量查询进行实验,我有一个程序,可以在不同的query.db上打开一个事务,并从我自己的框架中得到答案,该框架封装在一个对象中(它运行一个查询并将其运行时间打印在一个文件中) 因此,为了运行查询,我不使用Cypher 对于每个查询,我在query.db和data.db上打开两

我正在Java中使用Neo4j 2.3.0。我有16 GB的RAM,在MacOSX笔记本电脑上运行代码,使用“-Xmx12g-Xms12g”作为VM参数

我在Neo4JJavaAPI中遇到了“超出GC开销限制”的问题

为了对大量查询进行实验,我有一个程序,可以在不同的query.db上打开一个事务,并从我自己的框架中得到答案,该框架封装在一个对象中(它运行一个查询并将其运行时间打印在一个文件中)

因此,为了运行查询,我不使用Cypher

对于每个查询,我在query.db和data.db上打开两个事务,初始化我的框架并运行它。内存使用量略有增加,“GC开销”最终发生

try (Transaction txG = knowledgeGraph.beginTx()) {
     try (Transaction txQ = queryGraph.beginTx()) {
          MyObj myFramework = new MyObj();
          printTheResultsIntoTheFile(framework.run());
          myFramework =null;
          txQ.success();
          txQ.close();
以下是我为消除这个错误所做的一些努力:

  • 在使用监控程序转储堆后,我发现这个“org.neo4j.io.pagecache.impl.muninn.MuninnPageCache”有一些问题 因此,我尝试设置页面缓存大小并将其限制为较小的值:

    dataGraph=new-GraphDatabaseFactory().newEmbeddedDatabaseBuilder(MODELGRAPH\u DB\u路径)
    .setConfig(GraphDatabaseSettings.pagecache_memory,“500M”).newGraphDatabase()

  • 然而,仍然存在“内存泄漏”问题

  • tx.success()
    之后,我调用了
    tx.close()
    ,以确保它不使用内存

  • 使用我的框架(对象)查找查询的答案后,我显式地将其设置为null。
    topkFramework=null;

  • 我调用了
    System.gc();
    System.runFinalization();

  • 我将所有静态变量(如MyCacheServer或MyNeighborIndex)都更改为非静态变量,在每个查询中,我都将它们清除,并显式地将它们设置为null

    queryNodeIdSet.clear();
    queryNodeIdSet=null;
    queryNodeIdSet=newhashset();

  • 这是一个猜测(现在没有时间尝试),但我会试一试。Neo4j不支持嵌套事务。任何顶级事务(
    txG
    ,在您的情况下)都绑定到
    ThreadLocal
    。任何“嵌套”事务(
    txQ
    )都会变成
    PlaceboTransaction
    。因此,调用
    success()
    close()
    对它没有任何影响

    因此,当顶级事务打开时,您在子事务中访问的所有内容都保存在内存(堆)中,直到顶级事务完成。我知道这是两个不同的数据库,但仍然是
    ThreadLocal

    我认为您应该在每次关闭子事务时尝试关闭顶级事务。看看这是否有帮助。

    这是一个猜测(现在没有时间尝试),但我会试一试。Neo4j不支持嵌套事务。任何顶级事务(
    txG
    )都绑定到
    ThreadLocal
    。任何“嵌套”事务“事务(
    txQ
    )成为
    PlaceboTransaction
    。因此,对其调用
    success()
    close()
    没有任何效果

    因此,当顶级事务打开时,您在子事务中访问的所有内容都保存在内存(堆)中,直到顶级事务完成。我知道这是两个不同的数据库,但仍然是
    ThreadLocal


    我认为你应该尝试在每次关闭子级时关闭顶级级。看看这是否有帮助。

    在深入研究Neo4j之后,我发现它与一个接一个地创建大量查询图有关。虽然我在处理每个查询之后调用了db.shutdown(),但缓存似乎不会为空

    smallGraph = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(graphPath)
                .setConfig(GraphDatabaseSettings.pagecache_memory, "240k").newGraphDatabase();
    
    我已经添加了这个配置,并将其设置为最小可能的数量。现在,内存泄漏不会太多,不会破坏我的进程。在运行了大约1000个查询之后,它仍然在运行。早些时候,它在运行了200个查询之后消耗了我所有的内存(12GB)

    这是我的跟踪:

    Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    
        at org.neo4j.io.pagecache.impl.muninn.MuninnPageCache.<init>(MuninnPageCache.java:246)
    
        at org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory.createPageCache(ConfiguringPageCacheFactory.java:96)
    
        at org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory.getOrCreatePageCache(ConfiguringPageCacheFactory.java:87)
    
        at org.neo4j.kernel.impl.factory.PlatformModule.createPageCache(PlatformModule.java:277)
    
        at org.neo4j.kernel.impl.factory.PlatformModule.<init>(PlatformModule.java:154)
    
        at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.createPlatform(GraphDatabaseFacadeFactory.java:181)
    
        at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:124)
    
        at org.neo4j.kernel.impl.factory.CommunityFacadeFactory.newFacade(CommunityFacadeFactory.java:43)
    
        at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:108)
    
        at org.neo4j.graphdb.factory.GraphDatabaseFactory.newDatabase(GraphDatabaseFactory.java:129)
    
        at org.neo4j.graphdb.factory.GraphDatabaseFactory$1.newDatabase(GraphDatabaseFactory.java:117)
    
        at org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:185)
    
        at org.neo4j.graphdb.factory.GraphDatabaseFactory.newEmbeddedDatabase(GraphDatabaseFactory.java:79)
    
        at org.neo4j.graphdb.factory.GraphDatabaseFactory.newEmbeddedDatabase(GraphDatabaseFactory.java:74)
    
    原因:java.lang.OutOfMemoryError:超出GC开销限制
    位于org.neo4j.io.pagecache.impl.muninn.MuninnPageCache.(MuninnPageCache.java:246)
    位于org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory.createPageCache(ConfiguringPageCacheFactory.java:96)
    位于org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory.getOrCreatePageCache(ConfiguringPageCacheFactory.java:87)
    位于org.neo4j.kernel.impl.factory.PlatformModule.createPageCache(PlatformModule.java:277)
    位于org.neo4j.kernel.impl.factory.PlatformModule.(PlatformModule.java:154)
    位于org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.createPlatform(GraphDatabaseFacadeFactory.java:181)
    位于org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:124)
    位于org.neo4j.kernel.impl.factory.CommunityFacadeFactory.newFacade(CommunityFacadeFactory.java:43)
    位于org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:108)
    位于org.neo4j.graphdb.factory.GraphDatabaseFactory.newDatabase(GraphDatabaseFactory.java:129)
    位于org.neo4j.graphdb.factory.GraphDatabaseFactory$1.newDatabase(GraphDatabaseFactory.java:117)
    位于org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:185)
    位于org.neo4j.graphdb.factory.GraphDatabaseFactory.newEmbeddedDatabase(GraphDatabaseFactory.java:79)
    位于org.neo4j.graphdb.factory.GraphDatabaseFactory.newEmbeddedDatabase(GraphDatabaseFactory.java:74)
    
    在深入研究Neo4j之后,我发现它与一个接一个地创建大量查询图有关。虽然我在处理每个查询之后调用了db.shutdown(),但缓存似乎不会为空

    smallGraph = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(graphPath)
                .setConfig(GraphDatabaseSettings.pagecache_memory, "240k").newGraphDatabase();
    
    我已经添加了这个配置,并将其设置为最小可能的数量。现在是内存泄漏