如何解决Optaplanner 的内存泄漏问题
我有一个课程安排问题,其中包含用于分数计算的约束流。
在解决分配的堆不断增加的同时,几个小时后它甚至超过了 8GB,我得到了一个 java.lang.OutOfMemoryError: Java heap space
。
正如 optaplanner 文档中所述,在求解器阶段,堆大小应保持不变。 我需要有关此类行为可能存在的问题以及如何调试的建议。
Has optaplanners toList ConstraintCollector a bug? 中提供的 reproducer 将重现此行为。似乎带有 Collectors.toList()
的这个约束是我项目中导致泄漏的唯一约束。
我做了一些分析:占用增加内存的已分配对象属于类型
org.drools.core.util.index.TupleList
线程栈如下:
SwingWorker-pool-1-thread-3
at org.drools.core.reteoo.BaseLeftTuple.get(I)Lorg/drools/core/common/InternalFactHandle; (BaseLeftTuple.java:406)
at org.drools.modelcompiler.constraints.BindingEvaluator.getArgument(Lorg/drools/core/common/InternalFactHandle;Lorg/drools/core/common/InternalWorkingMemory;Lorg/drools/core/rule/Declaration;Lorg/drools/core/spi/Tuple;)Ljava/lang/Object; (BindingEvaluator.java:59)
at org.drools.modelcompiler.constraints.ConstraintEvaluator$InnerEvaluator.getArgument(Lorg/drools/core/common/InternalFactHandle;Lorg/drools/core/common/InternalWorkingMemory;Lorg/drools/core/rule/Declaration;Lorg/drools/core/spi/Tuple;)Ljava/lang/Object; (ConstraintEvaluator.java:234)
at org.drools.modelcompiler.constraints.ConstraintEvaluator$InnerEvaluator$_2.evaluate(Lorg/drools/core/common/InternalFactHandle;Lorg/drools/core/spi/Tuple;Lorg/drools/core/common/InternalWorkingMemory;)Z (ConstraintEvaluator.java:283)
at org.drools.modelcompiler.constraints.ConstraintEvaluator.evaluate(Lorg/drools/core/common/InternalFactHandle;Lorg/drools/core/spi/Tuple;Lorg/drools/core/common/InternalWorkingMemory;)Z (ConstraintEvaluator.java:117)
at org.drools.modelcompiler.constraints.LambdaConstraint.isAllowedCachedRight(Lorg/drools/core/spi/Tuple;Lorg/drools/core/rule/ContextEntry;)Z (LambdaConstraint.java:160)
at org.drools.core.common.TripleBetaConstraints.isAllowedCachedRight([Lorg/drools/core/rule/ContextEntry;Lorg/drools/core/spi/Tuple;)Z (TripleBetaConstraints.java:123)
at org.drools.core.phreak.PhreakJoinNode.doRightUpdatesProcessChildren(Lorg/drools/core/reteoo/LeftTuple;Lorg/drools/core/reteoo/LeftTuple;Lorg/drools/core/reteoo/RightTuple;Lorg/drools/core/common/TupleSets;[Lorg/drools/core/rule/ContextEntry;Lorg/drools/core/common/BetaConstraints;Lorg/drools/core/reteoo/LeftTupleSink;Lorg/drools/core/util/FastIterator;Lorg/drools/core/common/TupleSets;)Lorg/drools/core/reteoo/LeftTuple; (PhreakJoinNode.java:347)
at org.drools.core.phreak.PhreakJoinNode.doRightUpdates(Lorg/drools/core/reteoo/JoinNode;Lorg/drools/core/reteoo/LeftTupleSink;Lorg/drools/core/reteoo/BetaMemory;Lorg/drools/core/common/InternalWorkingMemory;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;)V (PhreakJoinNode.java:320)
at org.drools.core.phreak.PhreakJoinNode.doNode(Lorg/drools/core/reteoo/JoinNode;Lorg/drools/core/reteoo/LeftTupleSink;Lorg/drools/core/reteoo/BetaMemory;Lorg/drools/core/common/InternalWorkingMemory;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;)V (PhreakJoinNode.java:59)
at org.drools.core.phreak.RuleNetworkEvaluator.switchOndobetaNode(Lorg/drools/core/common/NetworkNode;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/InternalWorkingMemory;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;Lorg/drools/core/reteoo/LeftTupleSinkNode;Lorg/drools/core/reteoo/BetaMemory;Lorg/drools/core/reteoo/AccumulateNode$AccumulateMemory;)V (RuleNetworkEvaluator.java:569)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(Lorg/drools/core/reteoo/PathMemory;Lorg/drools/core/common/NetworkNode;Lorg/drools/core/common/Memory;[Lorg/drools/core/reteoo/SegmentMemory;ILorg/drools/core/common/TupleSets;Lorg/drools/core/common/InternalAgenda;Lorg/drools/core/util/LinkedList;ZLorg/drools/core/phreak/RuleExecutor;Lorg/drools/core/common/TupleSets;Lorg/drools/core/common/TupleSets;Lorg/drools/core/reteoo/LeftTupleSinkNode;)Z (RuleNetworkEvaluator.java:555)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(Lorg/drools/core/reteoo/PathMemory;Lorg/drools/core/common/NetworkNode;JLorg/drools/core/common/Memory;[Lorg/drools/core/reteoo/SegmentMemory;ILorg/drools/core/common/InternalAgenda;Lorg/drools/core/util/LinkedList;ZLorg/drools/core/phreak/RuleExecutor;Lorg/drools/core/common/TupleSets;Lorg/drools/core/reteoo/SegmentMemory;Lorg/drools/core/common/TupleSets;Lorg/drools/core/reteoo/LeftTupleSinkNode;)Lorg/drools/core/common/TupleSets; (RuleNetworkEvaluator.java:382)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(Lorg/drools/core/reteoo/PathMemory;Lorg/drools/core/common/NetworkNode;JLorg/drools/core/common/Memory;[Lorg/drools/core/reteoo/SegmentMemory;ILorg/drools/core/common/TupleSets;Lorg/drools/core/common/InternalAgenda;Lorg/drools/core/util/LinkedList;ZLorg/drools/core/phreak/RuleExecutor;)V (RuleNetworkEvaluator.java:342)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(Lorg/drools/core/reteoo/PathMemory;Lorg/drools/core/common/NetworkNode;JLorg/drools/core/common/Memory;[Lorg/drools/core/reteoo/SegmentMemory;ILorg/drools/core/common/TupleSets;Lorg/drools/core/common/InternalAgenda;Lorg/drools/core/util/LinkedList;ZLorg/drools/core/phreak/RuleExecutor;)V (RuleNetworkEvaluator.java:178)
at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(Lorg/drools/core/reteoo/PathMemory;Lorg/drools/core/phreak/RuleExecutor;Lorg/drools/core/common/InternalAgenda;)V (RuleNetworkEvaluator.java:136)
at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(Lorg/drools/core/common/InternalAgenda;)V (RuleExecutor.java:215)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(Lorg/drools/core/common/InternalAgenda;Lorg/kie/api/runtime/rule/AgendaFilter;II)I (RuleExecutor.java:89)
at org.drools.core.concurrent.AbstractRuleEvaluator.internalEvaluateAndFire(Lorg/kie/api/runtime/rule/AgendaFilter;IILorg/drools/core/phreak/RuleAgendaItem;)I (AbstractRuleEvaluator.java:33)
at org.drools.core.concurrent.SequentialRuleEvaluator.evaluateAndFire(Lorg/kie/api/runtime/rule/AgendaFilter;IILorg/drools/core/common/InternalAgendaGroup;)I (SequentialRuleEvaluator.java:43)
at org.drools.core.common.DefaultAgenda.fireLoop(Lorg/kie/api/runtime/rule/AgendaFilter;ILorg/drools/core/common/DefaultAgenda$RestHandler;Z)I (DefaultAgenda.java:1115)
at org.drools.core.common.DefaultAgenda.internalFireAllRules(Lorg/kie/api/runtime/rule/AgendaFilter;IZ)I (DefaultAgenda.java:1062)
at org.drools.core.common.DefaultAgenda.fireAllRules(Lorg/kie/api/runtime/rule/AgendaFilter;I)I (DefaultAgenda.java:1054)
at org.drools.core.impl.StatefulKNowledgeSessionImpl.internalFireAllRules(Lorg/kie/api/runtime/rule/AgendaFilter;I)I (StatefulKNowledgeSessionImpl.java:1347)
at org.drools.core.impl.StatefulKNowledgeSessionImpl.fireAllRules(Lorg/kie/api/runtime/rule/AgendaFilter;I)I (StatefulKNowledgeSessionImpl.java:1338)
at org.drools.core.impl.StatefulKNowledgeSessionImpl.fireAllRules()I (StatefulKNowledgeSessionImpl.java:1322)
at org.optaplanner.core.impl.score.stream.drools.DroolsConstraintSession.calculatescore(I)Lorg/optaplanner/core/api/score/score; (DroolsConstraintSession.java:72)
at org.optaplanner.core.impl.score.director.stream.ConstraintStreamscoreDirector.calculatescore()Lorg/optaplanner/core/api/score/score; (ConstraintStreamscoreDirector.java:74)
at org.optaplanner.core.impl.score.director.AbstractscoreDirector.doAndProcessMove(Lorg/optaplanner/core/impl/heuristic/move/Move;ZLjava/util/function/Consumer;)V (AbstractscoreDirector.java:225)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.doMove(Lorg/optaplanner/core/impl/localsearch/scope/LocalSearchMoveScope;)V (LocalSearchDecider.java:133)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(Lorg/optaplanner/core/impl/localsearch/scope/LocalSearchStepScope;)V (LocalSearchDecider.java:117)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(Lorg/optaplanner/core/impl/solver/scope/SolverScope;)V (DefaultLocalSearchPhase.java:71)
at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(Lorg/optaplanner/core/impl/solver/scope/SolverScope;)V (AbstractSolver.java:99)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(Ljava/lang/Object;)Ljava/lang/Object; (DefaultSolver.java:163)
at myCalculateClass.calculate
at mySwingWorker$1.doInBackground()
at javax.swing.SwingWorker$1.call()Ljava/lang/Object; (SwingWorker.java:304)
at java.util.concurrent.FutureTask.run()V (FutureTask.java:264)
at javax.swing.SwingWorker.run()V (SwingWorker.java:343)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1128)
at java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:628)
at java.lang.Thread.run()V (Thread.java:829)
解决方法
(只是在这里重复/扩展@hornisgrinde 的评论,所以这个问题有一个明确的答案。)
运行 mvn dependency:tree
(或等效的 gradle 命令),确保所有 optaplanner-* 和 drools-* 版本同步。
在这种情况下,类路径包含 optaplanner-test 8.3.0 和 optaplanner-core 8.7.0,我相信它被 optaplanner-tests 对 optaplanner-core 的传递依赖所掩盖。要完全避免此问题,请使用 optaplanner-bom。
<project>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-bom</artifactId>
<type>pom</type>
<version>8.8.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-test</artifactId>
<scope>test</scope>
</dependency>
...
</dependencies>
</project>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。