Changeset 17362 in josm for trunk/src


Ignore:
Timestamp:
2020-11-26T16:39:04+01:00 (4 years ago)
Author:
GerdP
Message:

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

  • fix memory leaks in SplitWayAction and SplitWayCommand
  • fix (not yet used) counter of modified relations
Location:
trunk/src/org/openstreetmap/josm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r17188 r17362  
    223223                setHighlightedWaySegments(Collections.emptyList());
    224224                DISPLAY_COUNT.decrementAndGet();
     225                if (getValue() != 1) {
     226                    newWays.forEach(w -> w.setNodes(null)); // see 19885
     227                }
    225228            }
    226229        }
     
    304307            }
    305308        });
     309        if (!splitWayCommand.isPresent()) {
     310            newWays.forEach(w -> w.setNodes(null)); // see 19885
     311        }
    306312    }
    307313
  • trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java

    r17359 r17362  
    2424import java.util.Set;
    2525import java.util.function.Consumer;
     26import java.util.stream.Collectors;
    2627
    2728import javax.swing.JOptionPane;
     
    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,
     
    396397        }
    397398
    398         switch (missingMemberStrategy) {
     399        try {
     400            switch (missingMemberStrategy) {
    399401            case GO_AHEAD_WITH_DOWNLOADS:
    400402                try {
     
    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            return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
     423        } finally {
     424            // see #19885
     425            wayToKeep.setNodes(null);
     426            analysis.cleanup();
    418427        }
    419428    }
     
    443452            }
    444453
    445             numberOfRelations++;
     454            boolean isSimpleCase = true;
    446455
    447456            Relation c = null;
     
    549558                        }
    550559                        relationAnalyses.add(new RelationAnalysis(c, rm, direction, missingWays));
     560                        isSimpleCase = false;
    551561                    }
    552562                }
    553563            }
    554 
    555             if (c != null) {
    556                 commandList.add(new ChangeCommand(r.getDataSet(), r, c));
     564            if (!isSimpleCase)
     565                numberOfRelations++;
     566            if (c != null && isSimpleCase) {
     567                if (!r.getMembers().equals(c.getMembers())) {
     568                    commandList.add(new ChangeMembersCommand(r, new ArrayList<>(c.getMembers())));
     569                    numberOfRelations++;
     570                }
     571                c.setMembers(null); // see #19885
    557572            }
    558573        }
     
    575590            warningTypes = warnings;
    576591            this.numberOfRelations = numberOfRelations;
     592        }
     593
     594        /**
     595         * Unlink temporary copies of relations. See #19885
     596         */
     597        void cleanup() {
     598            for (RelationAnalysis ra : relationAnalyses) {
     599                if (ra.relation.getDataSet() == null)
     600                    ra.relation.setMembers(null);
     601            }
    577602        }
    578603
     
    729754                }
    730755            }
     756        }
     757
     758        // add one command for each complex case with relations
     759        final DataSet ds = way.getDataSet();
     760        for (Relation r : analysis.getRelationAnalyses().stream().map(RelationAnalysis::getRelation).collect(Collectors.toSet())) {
     761            Relation orig = (Relation) ds.getPrimitiveById(r);
     762            analysis.getCommands().add(new ChangeMembersCommand(orig, new ArrayList<>(r.getMembers())));
     763            r.setMembers(null); // see #19885
    731764        }
    732765
Note: See TracChangeset for help on using the changeset viewer.