查询时出现Neo4J OutOfMemory错误

时间:2013-02-13 14:36:28

标签: neo4j

我最近开始使用Neo4J,到目前为止,我还没有找到我遇到的问题的答案,尤其是服务器。我正在使用1.8.1版本并在Windows上将服务器作为服务运行,而不是嵌入式服务。我拥有的图表有大约7米的节点和近11米的关系。

使用小查询和倍数,事情运行得很好。但是,当我试图撤回更复杂的查询(可能是数千行)时,事情会变得糟糕。如果我正在使用控制台,我将什么也得不到,然后在几分钟或更长时间后出现未定义的单词(它正试图在Javascript中执行某些操作,但我不确定是什么)。如果我在.NET中使用Neo4JClient,它会超时(我通过WCF服务工作)并且我怀疑我的问题是服务器端。

以下是一个示例cypher查询,它在控制台中引起了我的问题:

start begin = node:idx(ID="1234")
MATCH begin-[r1?:RELATED_TO]-n1-[r2?:RELATED_TO]-n2-[r3?:RELATED_TO]-n3-[r4?:RELATED_TO]-n4
RETURN begin.Title?, r1.RelationType?, n1.Title?, r2.RelationType?, n2.Title?, r3.RelationType?, n3.Title?, r4.RelationType?, n4.Title?;

我查看了日志,收到以下严重错误:

SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuffer.append(Unknown Source)
    at java.io.StringWriter.write(Unknown Source)
    at java.io.PrintWriter.newLine(Unknown Source)
    at java.io.PrintWriter.println(Unknown Source)
    at java.io.PrintWriter.println(Unknown Source)
    at org.neo4j.cypher.PipeExecutionResult$$anonfun$dumpToString$1.apply(PipeExecutionResult.scala:96)
    at org.neo4j.cypher.PipeExecutionResult$$anonfun$dumpToString$1.apply(PipeExecutionResult.scala:96)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.immutable.List.foreach(List.scala:45)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:96)
    at org.neo4j.cypher.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:124)
    at org.neo4j.cypher.javacompat.ExecutionResult.toString(ExecutionResult.java:90)
    at org.neo4j.shell.kernel.apps.Start.exec(Start.java:72)
    at org.neo4j.shell.kernel.apps.ReadOnlyGraphDatabaseApp.execute(ReadOnlyGraphDatabaseApp.java:32)
    at org.neo4j.shell.impl.AbstractAppServer.interpretLine(AbstractAppServer.java:127)
    at org.neo4j.shell.kernel.GraphDatabaseShellServer.interpretLine(GraphDatabaseShellServer.java:92)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:130)
    at org.neo4j.shell.impl.AbstractClient.evaluate(AbstractClient.java:114)
    at org.neo4j.server.webadmin.rest.ShellSession.evaluate(ShellSession.java:96)
    at org.neo4j.server.webadmin.rest.ConsoleService.exec(ConsoleService.java:123)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)

从一个受过教育的猜测角度来看堆栈跟踪,我是否正在撤回太多记录?因为扩展StringBuffer时内存不足。

我想知道GC是否可以扮演一个角色,所以我抓住了GCViewer。它似乎不是垃圾收集,我可以添加GCViewer的截图,如果你认为它会有用。

我已将JVM分配到默认值和8G内存之间的任何位置。以下是我的配置文件中的一些设置(我将尝试仅包含相关的设置)。如果您还需要,请告诉我。

Neo4J.properties

# Default values for the low-level graph engine
use_memory_mapped_buffers=false

# Keep logical logs, helps debugging but uses more disk space, enabled for legacy reasons
keep_logical_logs=true

Neo4J-server.properties

# HTTP logging is disabled. HTTP logging can be enabled by setting this property to 'true'.
org.neo4j.server.http.log.enabled=false 

Neo4J-Wrapper.conf(可能不合时宜地插在一起)

# Uncomment the following line to enable garbage collection logging
wrapper.java.additional.4=-Xloggc:data/log/neo4j-gc.log

# Setting a different Garbage Collector as recommended by Neo4J
wrapper.java.additional.5=-XX:+UseConcMarkSweepGC

# other beneficial settings that should boost performance
wrapper.java.additional.6=-d64
wrapper.java.additional.7=-server
wrapper.java.additional.8=-Xss1024k

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=1024

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=8000

感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

您的查询过于复杂。当你有一个如此大的图形而不是确定你不会达到你的堆内存限制时,你必须分配适当的内存。您可能希望使用此配置进行一些操作: io examples

但是,您的查询可以简化为:

start begin = node:idx(ID="1234")
MATCH p=begin-[r1:RELATED_TO*0..4]-n4
RETURN p

答案 1 :(得分:1)

Craig的问题是你使用Neo4j-Shell这只是一个操作工具,只是在发回之前收集内存中的数据,它从来没有打算处理大量的结果集。

您可能希望在启用了流媒体(X-Stream:true http-header)的情况下直接针对http端点运行查询,然后您就不再有问题了。