Java neo4j,REST和内存

我已经在Jersey tomcat下使用Neo4j Java嵌入式版本针对REST API部署了一个应用程序.
通过使用jconsole测量内存使用情况,我注意到每个REST调用都会增加200Mb的内存(我认为这是因为整个图形都已加载到内存中).因此,仅用5个调用,服务器便分配了1Gb的内存!要清理内存,我必须等待垃圾收集器(阈值设置为1Gb).

这是正常的行为是因为我使用的是neo4j Java嵌入式版本,还是我做错了什么?当API调用结束时,我应该怎么做以释放内存?

下面是示例代码:

@GET
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response getApi( @QueryParam("q")    String query){
try{
// new neo instance here with EmbeddedGraphDatabase
... some code
// stop neo
}catch(Exception ex){
// stop neo
}
return response.ok("json data here").build();   
}

谢谢,
丹尼尔

——–完整的班级代码———-

 import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.kernel.EmbeddedGraphDatabase;

@Path("/API")
public class API {

     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public Response apiCall(@QueryParam("q") String query){
        GraphDatabaseService graphDb; 
        try{
            // start neo
            graphDb = new EmbeddedGraphDatabase( "/var/neo4jdb/" );
            this.registerShutdownHook( graphDb );

            // API + NEO code here..

            // stop neo
            graphDb.shutdown();

        }catch(Exception ex){
            // stop neo
            graphDb.shutdown();
        }

        Response response = null;
        return response.ok("This is your query: "+query).build(); 

     }

    /**
     * Server shutdown
     */
    public 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();
                    }
                } );
    }

}

然后,我通过浏览器调用REST服务,例如http:// localhost:8080 / API?q = test

用辛格尔顿更新

     import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.QueryParam;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;

    import org.neo4j.graphdb.GraphDatabaseService;
    import org.neo4j.kernel.EmbeddedGraphDatabase;

    @Path("/API")
    public class API {

         @GET
         @Produces(MediaType.APPLICATION_JSON)
         public Response apiCall(@QueryParam("q") String query){
            GraphDatabaseService graphDb; 
            try{
                // start neo
                Neo4jSingleton neo4jInstance = new Neo4jSingleton();
                GraphDatabaseService graphDb = null;
                graphDb = neo4jInstance.getInstance(DB_PATH);
                this.registerShutdownHook( graphDb );

                // API + NEO code here..
                // cypher query
                        ExecutionEngine engine = new ExecutionEngine(graphDb); 
                        String queryString = "Cypher query code";
                        ExecutionResult result = engine.execute( queryString );
                        // fetch results here..

                // never stop neo now with singleton


            }catch(Exception ex){
                // stop neo
                graphDb.shutdown();
            }

            Response response = null;
            return response.ok("This is your query: "+query).build(); 

         }

        /**
         * Server shutdown
         */
        public 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();
                        }
                    } );
        }

    }
public class Neo4jSingleton {

    private static GraphDatabaseService db;

    public Neo4jSingleton() {

    }

    /*
     * il metodo di restituire un'unica istanza
     * contenente il database neo4j
     */
    public static GraphDatabaseService getInstance(String DB_PATH)
      {

        //Boolean isDbChange=verifyDbChange();

        if (db == null /*|| isDbChange*/)
        {
          db = new EmbeddedGraphDatabase(DB_PATH);
        }

        return db;
      }
}

解决方法:

您不能为每个请求都创建Neo4j实例.请只创建一次,然后将其传递给您,要么在静态字段中修改(因为您是为每个请求重新创建资源实例),要么在Neo4j服务器中使用带有@Context注入的Provider.

关于内存使用情况. Neo4j根据您的使用情况建立内部缓存,以在下一次更快地处理相同的查询.因此,这可能相当于一些已用的内存.

顺便说一句.您的图形有多大?您执行的典型操作是什么?

上一篇:注册asp.net


下一篇:带有反向代理和NGINX的Neo4j