2016-11-09 21 views
0

無論我使用的圖形和服務器的大小如何,只要我嘗試按dijkstra_one_to_many算法進行路由,我就會溢出我的堆。測試環境是一個m3.2xlarge,內存爲30GB,2x80gb SSD驅動器。Graphhopper Dijkstra一對多內存錯誤

java.lang.OutOfMemoryError: Java heap space

我已經找到了所述碼塊是在findEndNode方法內com.graphhopper.routing.DijkstraOneToMany問題:

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

這似乎從未找到結束節點和內部數據結構(分堆?)的增長和增長,直到我用完堆空間。這是爲什麼發生?

如果需要,我也可以發佈我的config.properties。感謝Peter爲我們製作了一款非常棒的開源軟件。

+0

那麼,你有沒有嘗試增加你的堆空間? (圖的大小和當前的堆大小是多少?)假設你的(未示出)isMaxVisitedNodesExceeded()正常工作,你沒有將你的'heap'字段變量運行到無窮大...... – BadZen

+0

I通過jvm args將堆大小設置爲27GB。北美pbf的圖形是4GB。也許我可以降低訪問的最大節點數,但我認爲我沒有正確使用算法類。 – Chadderall

回答

0

DijkstraOneToMany類目前不打算從外部(容易地)使用,例如,它不是線程安全的。你可以切換到一個簡單的Dijkstra而沒有不同的結束條件來降低簡單情況下的內存需求。

也就是說......可以有以下問題:

  • 確保您緩存到DijkstraOneToMany調用,因爲它創造大的初始數據結構
  • 再次:使用它只有一個線程(如通過ThreadLocal)
  • 它似乎永遠找不到結束節點 - >也許你使用QueryGraph它?由於我們在DijkstraOneToMany不知道的QueryGraph中創建所謂的虛擬節點,因此這不會真正起作用,而是嘗試選擇下一個塔節點,例如通過完全或手動避免QueryGraph通過EdgeIterator

謝謝彼得組建一個真棒一塊的開源軟件。

這不僅僅是我 - 它是一個社區的努力:)!

+0

因此,根據我的理解,這聽起來像我的查詢點可能會被捕獲到虛擬邊緣,DijkstraOneToMany會不斷遍歷基礎圖尋找一個它一無所知的ID? – Chadderall

+0

是的。查詢圖形將虛擬節點和邊緣ID引入例如。避免在算法中對兩個路口之間的地方進行特殊處理。 – Karussell