I'm using NDSolve inside a module, and I appear to have a memory leak. The relevant code is:
mpl = 1/Sqrt[6.70837*10^-39];
gsT = 106.75;
Sup[ΛI_?NumericQ, ΓI_?NumericQ] :=
Module[{a, ρr, Trad, tf, s, t},
ClearAll[tf]; ClearAll[Trad]; ClearAll[s];
tf = 10/ΓI;
ClearAll[a]; ClearAll[ρr];
s = NDSolve[{a'[t] == a[t]*Sqrt[(8 π)/(3 mpl^2) (ρr[t] + ΛI^4/a[t]^3 Exp[-ΓI t])], ρr'[t] + 4*Sqrt[(8 π)/(3 mpl^2) (ρr[t] + ΛI^4/a[t]^3 Exp[-ΓI t])] ρr[t] == ΓI ΛI^4/a[t]^3 Exp[-ΓI t], a[0] == 1, ρr[0] == 0}, {a, ρr}, {t, 0, tf}, MaxStepFraction -> 10^-5, MaxSteps -> 10^6];
{a = a /. s[[1]], ρr = ρr /. s[[1]]};
Trad[t_] := (30/(π^2 gsT) ρr[t])^(1/4);
Trad[tf]*a[tf]]
(I then evaluate Sup[x,y]
for a variety of x
and y
values; actually, my goal is to make a contour plot of it.)
As you can see, I'm explicitly clearing a[t]
and Rho[t]
before I call NDSolve
; however, these don't appear to get deleted after the module evaluates. Looking at the global variables, I have a$1058
, a$1186
, and so on. This is causing my memory usage to spiral out of control.
The problem seems to be that DownValues
are being assigned to these functions and so they're not getting cleared. (I have set $HistoryLength
to zero.)
How can I get the module to really, truly clear these functions?
Module
withresult = Trad[tf]*a[tf]; Clear[...]; result
, where you clear everything that doesn't seem to get cleared properly. $\endgroup$result = Trad[tf]*a[tf]; ClearAll[tf]; ClearAll[Trad]; ClearAll[s]; ClearAll[a]; ClearAll[\ \[Rho]r]; result
) which didn't work- I still get multiple copes in Global` $\endgroup$ClearAll
because it removes theTemporary
attribute. Use simplyClear
instead. I don't remember all the details of how this works, but see also the comment discussion under the answer I linked. $\endgroup$Clear
removes definitions associated with the symbol, but it doesn't remove the symbol itself.Remove
removed the symbol and replaced references to it (if they exist) with "something else" that is formatted asRemoved["name"]
but is really a special object. About why this happens: it's strange that e.g.a
isn't cleared properly because it doesn't in fact have a downvalue, only an ownvalue. It is likely thatNDSolve
creates some internal structures that hold references to the symbols that were used in the equation. It might help if ... $\endgroup$NDSolve
. It might also help to useBlock
instead ofModule
, asBlock
doesn't create temporary symbols, it just makes definitions temporary. The usual problem with using Block instead of Module is when you pass symbols to the function (the argumentsx
andy
) that have names identical with something you use internally. This cannot happen here because of?NumericQ
. So Block would be appropriate. All that said, it is still very annoying that this problem happens ... $\endgroup$