REST API用のJersey tomcatの下にneo4j Java埋め込みバージョンを使用してアプリをデプロイしました。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;
}
}