From Simon.Wotherspoon at utas.edu.au  Mon Jan 17 04:41:22 2011
From: Simon.Wotherspoon at utas.edu.au (Simon Wotherspoon)
Date: Mon, 17 Jan 2011 14:41:22 +1100
Subject: [Rd] isoreg memory leak?
Message-ID: <4D33BA62.7010902@utas.edu.au>


I believe there is a memory leak in isoreg in the current version of R, 
as I believe the following shows

 > gc()
          used (Mb) gc trigger (Mb) max used (Mb)
Ncells 120405  3.3     350000  9.4   350000  9.4
Vcells  78639  0.6     786432  6.0   392463  3.0
 > for(k in 1:100) {
+
+   y <- runif(10000)
+   isoreg(x,y)
+ }
 > rm(x)
 > rm(y)
 > gc()
          used (Mb) gc trigger (Mb) max used (Mb)
Ncells 121637  3.3     350000  9.4   350000  9.4
Vcells 578615  4.5    1300721 10.0  1300642 10.0
                ^^^


Looking at the C code, I believe the problem arises as a consequence of 
using SETLENGTH to resize the result near the very end of isoreg.c,
and the solution is to make a copy of iKnots.


SEXP R_isoreg(SEXP y)
{
     int n = LENGTH(y), i, ip, known, n_ip;
     double tmp, slope;
     SEXP yc, yf, iKnots, ans;
     const char *anms[] = {"y", "yc", "yf", "iKnots", ""};

     /* unneeded: y = coerceVector(y, REALSXP); */

     PROTECT(ans = mkNamed(VECSXP, anms));

     SET_VECTOR_ELT(ans, 0, y = y);
     SET_VECTOR_ELT(ans, 1, yc = allocVector(REALSXP, n+1));
     SET_VECTOR_ELT(ans, 2, yf = allocVector(REALSXP, n));
     SET_VECTOR_ELT(ans, 3, iKnots= allocVector(INTSXP, n));

... calculation ...

     SETLENGTH(iKnots, n_ip);
     UNPROTECT(1);
     return(ans);
}


But if this is the problem, I am at a bit of a loss as to what SETLENGTH 
is actually for in general.

Clearly my understanding of how allocation/gc works is a bit off here, 
but I can't see how else the leak may occur.  Hope this is more use than 
nuisance.

Simon.



[Rd] isoreg memory leak?
Simon Wotherspoon