2016-11-09 5 views
0

グラフのサイズや使用するサーバーに関係なく、dijkstra_one_to_manyアルゴリズムでルーティングしようとすると、ヒープがオーバーフローします。テスト環境は、30GBのRAMと2×80GBのSSDドライブを搭載したm3.2xlargeです。Graphhopper Dijkstra 1対多のメモリエラー

while (true) { 
     visitedNodes++; 
     EdgeIterator iter = outEdgeExplorer.setBaseNode(currNode); 
     while (iter.next()) { 
      int adjNode = iter.getAdjNode(); 
      int prevEdgeId = edgeIds[adjNode]; 
      if (!accept(iter, prevEdgeId)) 
       continue; 

      double tmpWeight = weighting.calcWeight(iter, false, prevEdgeId) + weights[currNode]; 
      if (Double.isInfinite(tmpWeight)) 
       continue; 

      double w = weights[adjNode]; 
      if (w == Double.MAX_VALUE) { 
       parents[adjNode] = currNode; 
       weights[adjNode] = tmpWeight; 
       heap.insert_(tmpWeight, adjNode); 
       changedNodes.add(adjNode); 
       edgeIds[adjNode] = iter.getEdge(); 

      } else if (w > tmpWeight) { 
       parents[adjNode] = currNode; 
       weights[adjNode] = tmpWeight; 
       heap.update_(tmpWeight, adjNode); 
       changedNodes.add(adjNode); 
       edgeIds[adjNode] = iter.getEdge(); 
      } 
     } 

     if (heap.isEmpty() || isMaxVisitedNodesExceeded() || isWeightLimitExceeded()) 
      return NOT_FOUND; 

     // calling just peek and not poll is important if the next query is cached 
     currNode = heap.peek_element(); 
     if (finished()) 
      return currNode; 

     heap.poll_element(); 
} 
``` 

エンド・ノードおよび内部データ構造を見つけることはありませんように見える(分:

java.lang.OutOfMemoryError: Java heap space

私はfindEndNode方法でcom.graphhopper.routing.DijkstraOneToMany内部の問題であるコードブロックを突き止めましたヒープ?)私がヒープスペースを使い果たすまで、成長し、成長し、成長する。なぜこうなった?

config.propertiesも必要に応じて投稿できます。素晴らしいオープンソースソフトウェアをまとめてくれたPeterに感謝します。

+0

さて、ヒープスペースを増やしてみましたか? (グラフの大きさと現在のヒープサイズは何ですか?)あなたの(表示されていない) 'isMaxVisitedNodesExceeded()'が正常に動作していて、 'heap'フィールド変数を無限大にしていないと仮定します... – BadZen

+0

I jvm argsを使ってヒープサイズを27GBに設定します。北アメリカpbfのグラフは4GBです。たぶん私は訪問されたノードの最大数を下げることができますが、私はアルゴリズムクラスを正しく使用しているとは思わない。 – Chadderall

答えて

0

DijkstraOneToManyクラスは、現在、外部から(簡単に)使用するようには意図されていません。スレッドセーフではありません。シンプルなケースのためのメモリ要件を下げるために、異なる仕上げ条件なしで簡単なダイクストラに切り替えることができます。

  • それが再び大きな初期データ構造
  • を作成して、あなたがDijkstraOneToManyへの呼び出しをキャッシュしていることを確認します:一つだけのスレッド(例えばからそれを使用すると...次の問題があることができ

    ThreadLocal経由で)

  • 最終ノードを見つけることはないようです - >たぶんあなたはそれでQueryGraphを使用しますか? DijkstraOneToManyが知らないQueryGraphにいわゆる仮想ノードを作成し、代わりに次のタワーノードを選択しようとすると、実際には機能しません。 EdgeIterator

を経由して、完全に、または手動QueryGraphを避け経て、オープンソースソフトウェアの素晴らしい作品を一緒に置くためのあなたにピーターをありがとうございます。

これは私だけではなく、コミュニティの努力です!:)

+0

私の理解では、私のクエリポイントが仮想エッジにスナップされ、DijkstraOneToManyが何も知らないIDを探しているベースグラフを常に横切っているように聞こえますか? – Chadderall

+0

はい。クエリグラフは、例えば、仮想ノードおよびエッジIDを導入する。 2つのジャンクション間のどこかの場所でアルゴリズムの特別な処理を避けてください。 – Karussell

関連する問題