13
$\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$
  • 3
    $\begingroup$ seems like you had a good answer here: stackoverflow.com/a/32069961/1004168 $\endgroup$ – george2079 Aug 18 '15 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$ – user5238191 Aug 18 '15 at 14:14
17
$\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$
  • $\begingroup$ Does ClearSystemCache basically take care of the problem on pre 10.2 versions? $\endgroup$ – march Aug 18 '15 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 '15 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 '15 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$ – user5238191 Aug 18 '15 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 '15 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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