java.lang.OutOfMemoryError: GC Overhead limit exceeded

Hi, @bcazabonne and all,

I’ve found a bug which leads to a memory leak, in tutorial.

I followed the orbit determination tutorial. It’s very wonderful, helping me starting to do an orbit determination.

Due to this GC overhead limit exceeded error, I google and google.

I tried to extract all java object in python following the previous mentioned topic. The error remains.

I noticed that someone says a WoW tool named VisualVM (https://visualvm.github.io/), which can be used to monitor the memory of VM. It’s really a powerful tool actually.

Here’s a dumped heap. We can see that there is a loop reference between lsBuilder and observer.

I checked the src of tutorial.

In the class org.orekit.tutorials.estimation.common.AbstractOrbitDetermination, new an org.orekit.tutorials.estimation.common.OrbitDeterminationObserver instance and set it as the estimator’s observer.

            // Set the observer and estimate orbit
            estimator.setObserver(new OrbitDeterminationObserver(initialGuess,
                                                                 logStream,
                                                                 estimator));

In the method setObserver of class org.orekit.estimation.leastsquares.BatchLSEstimator, the property observer is assigned. That is, the estimator refers to the observer.

   /** Set an observer for iterations.
     * @param observer observer to be notified at the end of each iteration
     */
    public void setObserver(final BatchLSObserver observer) {
        this.observer = observer;
    }

And in the construct of class OrbitDeterminationObserver, the property estimator is assigned by the parameter estimator. That is, the observer refers to the estimator. A loop occurs.

    public OrbitDeterminationObserver(final Orbit initialGuess,
                                      final PrintStream logStream,
                                      final BatchLSEstimator estimator) {
        this.previousPV = initialGuess.getPVCoordinates();
        this.logStream  = logStream;
        this.estimator  = estimator;
        String header = FORMAT_HEADER;
        header = addParametersNames(header,
                                    estimator.getOrbitalParametersDrivers(true),
                                    estimator.getPropagatorParametersDrivers(true),
                                    estimator.getMeasurementsParametersDrivers(true));
        System.out.format(Locale.US, header);
        if (logStream != null) {
            logStream.format(Locale.US, header);
        }
    }

It does not matter in simple mode, or just one run orbit determination. For a massive batch orbit determination, it leads to memory out error.

The reference of observer to the estimator should be removed, by deleting the observer’s property estimator.