【问题标题】:Graphhopper Dijkstra One-To-Many Memory ErrorGraphhopper Dijkstra 一对多内存错误
【发布时间】:2017-03-23 21:01:38
【问题描述】:

无论图表的大小和我使用的服务器如何,每当我尝试通过 dijkstra_one_to_many 算法进行路由时,都会溢出我的堆。测试环境是一个 m3.2xlarge,具有 30gb 的 RAM 和 2x80gb SSD 驱动器。

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 编写了一款很棒的开源软件。

【问题讨论】:

  • 嗯,你试过增加你的堆空间吗? (图表有多大,当前堆大小是多少?)假设您的(未显示)isMaxVisitedNodesExceeded() 工作正常,您没有将heap 字段变量运行到无穷大...
  • 我通过 jvm args 将堆大小设置为 27gb。北美pbf的图是4gb。也许我可以降低访问的最大节点数,但我认为我没有正确使用算法类。

标签: java graph heap-memory dijkstra graphhopper


【解决方案1】:

DijkstraOneToMany 类目前不打算(轻松)从外部使用,例如它不是线程安全的。您可以切换到没有不同完成条件的简单 Dijkstra 以降低简单案例的内存需求。

也就是说……可能存在以下问题:

  • 确保缓存对 DijkstraOneToMany 的调用,因为它会创建大型初始数据结构
  • 再次:仅在一个线程中使用它(例如通过 ThreadLocal)
  • 似乎永远找不到结束节点 -> 也许你使用了 QueryGraph 呢?这不会真正起作用,因为我们在 QueryGraph 中创建 DijkstraOneToMany 不知道的所谓虚拟节点,而是尝试选择下一个塔节点,例如通过完全避免 QueryGraph 或通过 EdgeIterator 手动避免

感谢 Peter 编写了一款很棒的开源软件。

这不仅仅是我 - 这是一个社区的努力:)!

【讨论】:

  • 所以根据我的理解,听起来我的查询点可能会被捕捉到虚拟边缘,并且 DijkstraOneToMany 不断遍历基本图以寻找它一无所知的 ID?
  • 是的。查询图将虚拟节点和边 ID 引入例如。避免在算法中对两个路口之间的位置进行特殊处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 2012-07-01
  • 2014-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多