14
$\begingroup$

Bug introduced in 6.0 and fixed in 10.2.0


NIntegrate uses memory and does not release it. For long loops with NIntegrate, memory goes up and computation slows down dramatically. Consider this specific example that uses 40 MB:

NI[z_?NumericQ, b0_?NumericQ] := NIntegrate[E^-Abs[(y - z)], {y, -b0, b0}]
m1 = MemoryInUse[];
For[i = 1, i < 10000, i++; NI[RandomReal[], .5]] // AbsoluteTiming
m2 = MemoryInUse[];
m2 - m1

Result:

{117.606048, Null}

40405872

How can we make NIntegrate release the memory?

$\endgroup$
2
  • 3
    $\begingroup$ seems like you had a good answer here: stackoverflow.com/a/32069961/1004168 $\endgroup$
    – george2079
    Aug 18, 2015 at 13:40
  • $\begingroup$ Thanks. But the problem is not about the one-shot memory usage of loading the package(s) of NIntegrate[]. It is about the use of memory after each execution of NIntegrate[]. stackoverflow.com/a/32069961/1004168 has exactly the same issue. $\endgroup$ Aug 18, 2015 at 14:14

1 Answer 1

18
$\begingroup$

The memory leak in NIntegrate is a bug and has been fixed as of version 10.2.0. Earlier versions would lose around 720 bytes per evaluation for this example, which could not be recovered without restarting the kernel.

ClearSystemCache[] should be used to make sure the memory is released. Using version 10.2:

NI[z_?NumericQ, b0_?NumericQ] := 
  NIntegrate[E^-Abs[y - z], {y, -b0, b0}];
NI[RandomReal[], .5]; (* NIntegrate autoloading *)
m1 = MemoryInUse[];
For[i = 1, i < 1000, i++; NI[RandomReal[], .5]; ClearSystemCache[]];
m2 = MemoryInUse[];
m2 - m1

(* -12744 *)

Also, if generating many outputs, it may be useful to set $HistoryLength = 0 or another small number.

We can evaluate the following to test whether the NIntegrate call leaks any memory:

Block[{$HistoryLength = 0}, ClearSystemCache[]; 
 Take[Table[before = MemoryInUse[]; 
   NIntegrate[E^-Abs[y - RandomReal[]], {y, -.5, .5}]; 
   ClearSystemCache[]; MemoryInUse[] - before, {10000}], -20]]

Version 10.2.0 shows no leak,

(* {0, 0, 0, 0, -64, 64, 0, 0, -64, 64, 0, 0, -64, 64, 0, 0, 0, 0, 0, 0} *)

while version 10.1.0 does

(* {656, 720, 656, 592, 720, ..., 656, 656, 656, 656, 656, 656} *)
$\endgroup$
5
  • $\begingroup$ Does ClearSystemCache basically take care of the problem on pre 10.2 versions? $\endgroup$
    – march
    Aug 18, 2015 at 15:21
  • $\begingroup$ Just checking in v9 ClearSystemCache[] cuts the leak about in half, but it is still there ( about 1.2 kb/eval with ClearSystemCache[] in the loop ) $\endgroup$
    – george2079
    Aug 18, 2015 at 15:31
  • 3
    $\begingroup$ @march No, it wouldn't help as there is a genuine memory leak in earlier versions. I've edited the answer to clarify this. $\endgroup$
    – ilian
    Aug 18, 2015 at 15:31
  • $\begingroup$ Indeed, ClearSystemCache[] releases only 1/2 of the memory on my Mathematica 10.0. It will not solve my problems as I have to use a loop that is very intensive in NIntegrate[]... Is there a version or option of NIntegrate that does release the memory? (I wish I should not re-program the function...) $\endgroup$ Aug 18, 2015 at 15:40
  • $\begingroup$ If you have a simple integral (not requiring adaptive sampling, etc) you can implement your own integration using Simpsons rule or some such. That's likely a good approach for this specific example. ( in the simple case its only a few lines of code ) $\endgroup$
    – george2079
    Aug 18, 2015 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.