title: Java neo4j, REST and memory
body: <p>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).</p>
  
  <p>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?</p>
  
  <p>Here example code:</p>
  
  <pre><code>@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();   
  }
  </code></pre>
  
  <p>Thanks,
  Daniele</p>
  
  <p>-------- COMPLETE CLASS CODE ----------</p>
  
  <pre><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();
                      }
                  } );
      }
  
  }
  </code></pre>
  
  <p>And then I call the REST service via browser like this <code>http://localhost:8080/API?q=test</code></p>
  
  <h2>UPDATED WITH SINGLETON</h2>
  
  <pre><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
                  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;
        }
  }
  </code></pre>