Ignore:
Timestamp:
2020-11-25T11:50:22+01:00 (3 years ago)
Author:
GerdP
Message:

see #19885: memory leak with "temporary" objects in validator and actions

  • (hopefully) fix memory leaks in complex actions
  • handle complex cases with presets and RelationEditor

I hope these changes don't break plugins which extend or overwrite RelationEditor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java

    r17163 r17358  
    1717import java.util.HashSet;
    1818import java.util.Iterator;
     19import java.util.LinkedHashSet;
    1920import java.util.LinkedList;
    2021import java.util.List;
     
    9091     * @param newSelection The new list of selected primitives ids (which is saved for later retrieval with {@link #getNewSelection})
    9192     * @param originalWay The original way being split (which is saved for later retrieval with {@link #getOriginalWay})
    92      * @param newWays The resulting new ways (which is saved for later retrieval with {@link #getOriginalWay})
     93     * @param newWays The resulting new ways (which is saved for later retrieval with {@link #getNewWays})
    9394     */
    9495    public SplitWayCommand(String name, Collection<Command> commandList,
     
    402403                } catch (OsmTransferException e) {
    403404                    ExceptionDialogUtil.explainException(e);
     405                    analysis.cleanup();
    404406                    return Optional.empty();
    405407                }
    406408                // If missing relation members were downloaded, perform the analysis again to find the relation
    407409                // member order for all relations.
     410                analysis.cleanup();
    408411                analysis = analyseSplit(way, wayToKeep, newWays);
    409                 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
     412                break;
    410413            case GO_AHEAD_WITHOUT_DOWNLOADS:
    411414                // Proceed with the split with the information we have.
    412415                // This can mean that there are no missing members we want, or that the user chooses to continue
    413416                // the split without downloading them.
    414                 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
     417                break;
    415418            case USER_ABORTED:
    416419            default:
    417420                return Optional.empty();
     421        }
     422        try {
     423            return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
     424        } finally {
     425            // see #19885
     426            wayToKeep.setNodes(null);
     427            analysis.cleanup();
    418428        }
    419429    }
     
    465475                    }
    466476                    if (c == null) {
    467                         c = new Relation(r);
     477                        c = new Relation(r); // #19885: will be removed later
    468478                    }
    469479
     
    552562                }
    553563            }
    554 
    555             if (c != null) {
    556                 commandList.add(new ChangeCommand(r.getDataSet(), r, c));
    557             }
    558564        }
    559565        changedWay.setNodes(null); // see #19885
     
    575581            warningTypes = warnings;
    576582            this.numberOfRelations = numberOfRelations;
     583        }
     584
     585        /**
     586         * Unlink temporary copies of relations. See #19885
     587         */
     588        void cleanup() {
     589            for (RelationAnalysis ra : relationAnalyses) {
     590                if (ra.relation.getDataSet() == null)
     591                    ra.relation.setMembers(null);
     592            }
    577593        }
    578594
     
    688704        }
    689705
     706        Set<Relation> modifiedRelations = new LinkedHashSet<>();
    690707        // Perform the split.
    691708        for (RelationAnalysis relationAnalysis : analysis.getRelationAnalyses()) {
     
    729746                }
    730747            }
     748            modifiedRelations.add(relation);
     749        }
     750        for (Relation r : modifiedRelations) {
     751            DataSet ds = way.getDataSet();
     752            Relation orig = (Relation) ds.getPrimitiveById(r);
     753            analysis.getCommands().add(new ChangeMembersCommand(orig, new ArrayList<>(r.getMembers())));
     754            r.setMembers(null); // see #19885
    731755        }
    732756
Note: See TracChangeset for help on using the changeset viewer.