When submachine! = null, the entry method performs submachine.addStateListener, but in the exit approach because completionListeners is empty, which could lead to an increase in submachine stateListener has not been released, Lead to the state machine. With the increase of the number of executions CompositeStateMachineLinsterer.stateChanged method performs slower and slower
The relevant codes are as follows:
@Override
public void exit(StateContext<S, E> context) {
if (submachine != null) {
for (StateMachineListener<S, E> l : completionListeners) {
submachine.removeStateListener(l);
}
} else if (!regions.isEmpty()) {
for (Region<S, E> region : regions) {
for (StateMachineListener<S, E> l : completionListeners) {
region.removeStateListener(l);
}
}
}
completionListeners.clear();
cancelStateActions();
stateListener.onExit(context);
disarmTriggers();
}
@Override
public void entry(StateContext<S, E> context) {
if (submachine != null) {
final StateMachineListener<S, E> l = new StateMachineListenerAdapter<S, E>() {
@Override
public void stateContext(StateContext<S, E> stateContext) {
if (stateContext.getStage() == Stage.STATEMACHINE_STOP) {
if (stateContext.getStateMachine() == submachine && submachine.isComplete()) {
completionListeners.remove(this);
submachine.removeStateListener(this);
if (completionListeners.isEmpty()) {
notifyStateOnComplete(stateContext);
}
}
}
}
};
submachine.addStateListener(l);
} else if (!regions.isEmpty()) {
for (final Region<S, E> region : regions) {
final StateMachineListener<S, E> l = new StateMachineListenerAdapter<S, E>() {
@Override
public void stateContext(StateContext<S, E> stateContext) {
if (stateContext.getStage() == Stage.STATEMACHINE_STOP) {
if (stateContext.getStateMachine() == region && region.isComplete()) {
completionListeners.remove(this);
region.removeStateListener(this);
if (completionListeners.isEmpty()) {
notifyStateOnComplete(stateContext);
}
}
}
}
};
completionListeners.add(l);
region.addStateListener(l);
}
}
@Override
public void stateChanged(State<S, E> from, State<S, E> to) {
for (Iterator<StateMachineListener<S, E>> iterator = getListeners().reverse(); iterator.hasNext();) {
StateMachineListener<S, E> listener = iterator.next();
try {
listener.stateChanged(from, to);
} catch (Throwable e) {
log.warn("Error during stateChanged", e);
}
}
}
When submachine! = null, the entry method performs submachine.addStateListener, but in the exit approach because completionListeners is empty, which could lead to an increase in submachine stateListener has not been released, Lead to the state machine. With the increase of the number of executions CompositeStateMachineLinsterer.stateChanged method performs slower and slower
The relevant codes are as follows:
@Override public void exit(StateContext<S, E> context) { if (submachine != null) { for (StateMachineListener<S, E> l : completionListeners) { submachine.removeStateListener(l); } } else if (!regions.isEmpty()) { for (Region<S, E> region : regions) { for (StateMachineListener<S, E> l : completionListeners) { region.removeStateListener(l); } } } completionListeners.clear(); cancelStateActions(); stateListener.onExit(context); disarmTriggers(); }