2016-05-24 2 views
0

クラスV1のすべての頂点とクラスV2のすべての頂点の間にエッジを作成する必要があります。私のクラスはそれぞれ2〜3百万の頂点を持っています。 SELECT * FROM V1、SELECT * FROM V2を持つdouble forループは、Java OutOfMemory(ヒープスペース)エラーを発生します(下記参照)。これはオフラインのプロセスで、必要に応じて1回または2回実行されます(頻繁な操作ではありません)。グラフはユーザー自身によって定期的に更新されないため、自分でのみ更新されます。 これを避けるには、どのようにバッチで(SELECT ... LIMITまたはg.getvertices()を使用して)行うことができますか?Orientdb - 何百万もの頂点を持つSQLクエリでJava OutOfMemoryエラーが発生する

 OrientGraphNoTx G = MyOrientDBFactory.getNoTx(); 
     G.setUseLightweightEdges(false); 
     G.declareIntent(new OIntentMassiveInsert()); 

     for (Vertex p1 : (Iterable<Vertex>) EG.command(new OCommandSQL("SELECT * FROM V1")).execute()) 
     { 
      for (Vertex p2 : (Iterable<Vertex>) EG.command(new OCommandSQL("SELECT * FROM V2")).execute()) 
      { 
       if (p1.getProperty("prop1")==p2.getProperty("prop1") 
       { 
        //p1.addEdge("MyEdge", p2); 
        EG.command(new OCommandSQL("create edge MyEdge from" + p1.getId() +"to "+ p2.getId() + " retry 100")).execute(); 
       } 
      } 
     } 
     G.shutdown(); 

VMオプション-Xmx4096mと-Dstorage.diskCache.bufferSize = 7200

のNetBeans 8.1は、Java /グラフAPIとOrientDB 2.1.5:

ここに私のコードです


コンソールのエラーメッセージ:

回避策として

2016-05-24 15:48:06:112 INFO {db=MyDB} [TIP] Query 'SELECT * FROM V1' returned a result set with more than 10000 records. Check if you really need all these records, or reduce the resultset by using a LIMIT to improve both performance and used RAM [OProfilerStub]java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid7896.hprof ...

Netbeansの出力でのエラーメッセージ

Exception in thread "main" com.orientechnologies.orient.enterprise.channel.binary.OResponseProcessingException: Exception during response processing. at com.orientechnologies.orient.enterprise.channel.binary.OChannelBinaryAsynchClient.throwSerializedException(OChannelBinaryAsynchClient.java:443) at com.orientechnologies.orient.enterprise.channel.binary.OChannelBinaryAsynchClient.handleStatus(OChannelBinaryAsynchClient.java:398) at com.orientechnologies.orient.enterprise.channel.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:282) at com.orientechnologies.orient.enterprise.channel.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:171) at com.orientechnologies.orient.client.remote.OStorageRemote.beginResponse(OStorageRemote.java:2166) at com.orientechnologies.orient.client.remote.OStorageRemote.command(OStorageRemote.java:1189) at com.orientechnologies.orient.client.remote.OStorageRemoteThread.command(OStorageRemoteThread.java:444) at com.orientechnologies.orient.core.command.OCommandRequestTextAbstract.execute(OCommandRequestTextAbstract.java:63) at com.tinkerpop.blueprints.impls.orient.OrientGraphCommand.execute(OrientGraphCommand.java:49) at xx.xxx.xxx.xx.MyEdge.(MyEdge.java:40) at xx.xxx.xxx.xx.GMain.main(GMain.java:60) Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

+0

Iterable v2 =(Iterable )EG.command(新しいOCommandSQL( "SELECT * FROM V2"))を使用できます。あなたの先端をありがとう、私はそれをやったし、まだ正確に同じ問題を抱えている { (){ } 場合}あなたのコード –

+0

@AlessandroRotaを最適化するために...: (V2頂点P2)について – ChrisB

答えて

0

Iterable<Vertex> cv1= g.command(new OCommandSQL("SELECT count(*) FROM V1")).execute(); 
long counterv1=cv1.iterator().next().getProperty("count"); 

int[] ids=g.getRawGraph().getMetadata().getSchema().getClass("V1").getClusterIds(); 

long repeat=counterv1/10000; 
long rest=counterv1-(repeat*10000); 

List<Vertex> v1=new ArrayList<Vertex>(); 
int rid=0; 
for(int i=0;i<repeat;i++){ 
    Iterable<Vertex> v= g.command(new OCommandSQL("SELECT * FROM V1 WHERE @rid >= " + ids[0] + ":" + rid + " limit 10000")).execute(); 
    CollectionUtils.addAll(v1, v.iterator()); 
    rid=10000*(i+1); 
} 
if(rest>0){ 
    Iterable<Vertex> v=g.command(new OCommandSQL("SELECT * FROM V1 WHERE @rid >= " + ids[0] + ":" + rid + " limit "+ rest)).execute(); 
    CollectionUtils.addAll(v1, v.iterator()); 
} 

のようなコードを使用することができ、それがお役に立てば幸いです。

関連する問題