Java环境下Google OR-Tools跨线程调用getArcCostForVehicle内存报错
问题原因
Google OR-Tools的Java API是基于JNI对C原生实现的封装,RoutingModel等核心求解对象的实际内存、运行上下文都分配在C原生堆上,Java侧仅持有指向原生对象的指针引用。
- OR-Tools原生层的
RoutingModel相关对象默认不支持跨线程访问,对象的状态上下文、内存索引都和首次创建/调用solveWithParameters的线程绑定 - 跨线程调用
RoutingModel的方法时,当前线程的原生上下文不存在对应对象的内存索引,JNI调用时就会触发内存找不到对应值的崩溃,和提供的报错栈特征完全匹配。
可行解决方案
- 优先使用线程绑定方案:将
RoutingModel的全生命周期操作(实例创建、参数配置、调用求解、读取结果)都放在同一个线程中执行。你可以在求解完成后,把所有需要的结果(包括路段成本、路径序列、总开销等)一次性读取出来,封装成自定义的普通Java对象(POJO),再将该POJO传递给其他线程做后续业务处理,从根源上避免跨线程操作原生RoutingModel对象。 - 并发求解场景方案:如果业务需要多线程同时处理多个路径规划任务,给每个线程分配独立的
RoutingModel实例,不要在多线程间共享同一个实例,每个实例的所有操作都绑定到所属的单个线程。 - 注意事项:在完成所有结果读取前,必须持有
RoutingModel的Java强引用,避免GC提前回收Java侧对象触发原生内存析构,也会引发同类报错。
内容的提问来源于stack exchange,提问作者Nane Petrosyan
相关产品推荐
相关产品推荐

