Java neo4j、REST 和内存 [英] Java neo4j, REST and memory

查看:25
本文介绍了Java neo4j、REST 和内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've deployed an app using neo4j java embedded version under Jersey tomcat for REST API. By measuring memory usage with jconsole I noticed each REST call adds 200Mb of memory (which I think it's because the entire graph gets loaded into memory). Therefore with just 5 calls, server allocates 1Gb of memory, which is a lot! To clean up memory I have to wait garbage collector (threshold set to 1Gb).

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

Is it a normal behavior because I'm using the neo4j java embedded version or am I doing something terribly wrong? What I'm supposed to do to free memory when the API call ends?

这里的示例代码:

@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();   
}

谢谢,丹尼尔

--------完整的类代码 ----------

-------- COMPLETE CLASS CODE ----------

 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

And then I call the REST service via browser like this 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 实例.请只创建一次然后将其传入,要么在静态字段中使用 hacky(因为您为每个请求重新创建资源实例),要么在 Neo4j 服务器中使用注入了 @Context.

You must not create Neo4j instance for every request. Please create it just once and then pass it in, either hacky in a static field (as you're resource instance is recreate for each request) or as in Neo4j server with an Provider which is injected with @Context.

关于内存使用.Neo4j 根据您的使用情况构建内部缓存,以便下次更快地处理相同的查询.所以这可能会占用一些已用内存.

Regarding memory usage. Neo4j builds up internal caches according to your usage to serve the same queries faster the next time. So that might amount for some of the used memory.

顺便说一句.你的图有多大,你做的典型操作是什么?

Btw. how large is your graph and what are the typical operations you do?

这篇关于Java neo4j、REST 和内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆