2016-11-09 6 views
0

그래프의 크기와 내가 사용하는 서버에 관계없이 dijkstra_one_to_many 알고리즘으로 라우트를 시도 할 때마다 힙이 오버플로됩니다. 테스트 환경은 30GB RAM과 2x80GB SSD 드라이브를 갖춘 m3.2xlarge입니다.Graphhopper Dijkstra 일대 다 메모리 오류

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 클래스는 현재 외부에서 쉽게 (예 :. 스레드로부터 안전하지 않습니다. 다른 마무리 조건없이 간단한 Dijkstra로 전환하여 간단한 경우의 메모리 요구 사항을 줄일 수 있습니다.

  • 하는 것이
  • 다시 큰 초기 데이터 구조체를 생성 당신이 DijkstraOneToMany에 대한 호출을 캐시 있는지 확인하십시오 :했다 ... 다음과 같은 문제가있을 수

    하나 개의 스레드에서 사용 (예 : ThreadLocal을 통해)

  • 끝 노드를 찾지 못하는 것 같습니다 -> 아마도 QueryGraph를 사용했을까요? DijkstraOneToMany가 모르는 QueryGraph에 가상 노드라고 불리는 가상 노드를 생성 할 때 실제로 작동하지 않습니다. 대신 다음 타워 노드를 선택하려고 시도합니다. EdgeIterator를 통해 완전히 또는 수동으로 QueryGraph을 피하는를 통해

함께 오픈 소스 소프트웨어의 멋진 조각을 넣어 주셔서에게 베드로 감사드립니다.

나만의 것이 아니 었습니다.

+0

내 이해에서 내 쿼리 포인트가 가상 가장자리에 찍히고 DijkstraOneToMany가 계속해서 기본 그래프를 탐색하여 아무것도 모르는 ID를 찾는 것처럼 들리겠습니까? – Chadderall

+0

예. 쿼리 그래프는 예를 들어 가상 노드와 에지 ID를 도입합니다. 두 접합점 사이 어딘가에 대한 알고리즘의 특수 처리를 피하십시오. – Karussell