Hello Simon, Thanks much for the replies. It makes sense now and I'm on the right track. I'll explain why this might happen.
I've written a package caller rterra [1] which essentially allows the R user to write extensions in Lua. The extensions are JIT compiled via LuaJIT. For deterministic performance the user can write their extension in Terra. To make memory management easier for the extension writer, i wanted auto memory management. Consider the following code sample which calls an extension written in Lua to compute a sum by traversing some JSON 1. In R, the extension, is called as l <- terra("computeCountsByDayAndCountry", values, c("2013-01-01","2014-12-31")) 2. In Lua, the code looks like function computeCountsByDayAndCountry(jsonstr,dateRange) local x,y = R.Robj(jsonstr),R.Robj(dateRange) local dstart,dend = ffi.string(y[0]),ffi.string(y[1]) local f = R.Robj{type='str', length =#x} R.autoProtect(f) -- line 'A' for index = 0, #x-1 do local ok,jc = pcall(cjson.decode,ffi.string(x[index][0])) if ok then f[index] = cjson.encode( _computeSearchCountsCountry(jc,dstart,dend)) else f[index] = cjson.encode({}) end end return f end When this returns, the SEXP contained in 'f' is associated with 'l' (in step 1) LuaJIT has garbage collection. At http://luajit.org/ext_ffi_api.html, when 'f' above (line 'A') get garbage collected, a finalizer is run. The call to autoProtect does 1. calls PReserveObject on f.sexp 2. sets the finalizer to call ReleaseObject. When the user calls an extension written in Lua again, 'f' will get garbage collected by Lua (assuming it has no references in Lua). And yes, there will be a mem leak, *iff* the user *never* calls an extension written in Lua again, otherwise no. And of course, the user can not call autoProtect, but can manage it themselves, i.e. using R.protect and R.unprotect. Thanks for the insight http://people.mozilla.org/~sguha/blog/2013/08/01/rterra_first_post.html Cheers Saptarshi On Thu, Mar 6, 2014 at 7:05 PM, Simon Urbanek <simon.urba...@r-project.org> wrote: > On Mar 6, 2014, at 5:32 PM, Saptarshi Guha <saptarshi.g...@gmail.com> wrote: > >> Hello, >> >> This is a question that probably reveals my lack of understanding. >> In a C function (call it cfunc), i created a SEXP, called S, and then >> called R_PreserveObject on S. >> >> I returned the SEXP to the calling R function (call it rfunc). Note, I >> didn't call >> R_ReleaseObject on S. >> >> v <- .Call("cfunc") >> >> So, are the following statements correct >> >> 1. S is 'doubly' protected from the GC by being associated both with 'v' >> and because it has been added to the precious list (via a call to >> R_PreserveObject without ReleaseObject being called) >> > > yes > > >> 2. I have another C function called cfunc2. In cfunc2, I call >> R_ReleaseObject on S. S , however, is still protected from the GC, because >> it is associated with 'v' >> > > yes (assuming the binding to v still exists at that point). Note, however, > that is such a case you R_PreserveObject() is pointless since you don't need > to protect it on exit (that's in fact the convention - return results are > never protected). > > >> Is (1) and (2) correct? >> >> I have not used R_protect/unprotect, because if I return from cfunc without >> the equivalent number of unprotects, i get 'unbalanced stack' warnings. I'd >> rather not have to worry about that because i intend to balance it later. >> > > Normally, you should not keep the result of a function protected since it > means you *have* to guarantee the unprotect at a later point. That is in > general impossible to guarantee unless you have another object that is > holding a reference that will be cleared by an explicitly registered > finalizer. So unless that is the case, you are creating an explicit leak = > bad. If you don't have as stack-like design, you can always use explicitly > managed object for the lifetime (personally, I prefer that) since all chained > objects are protected by design, or use REPROTECT. > > Cheers, > Simon > > >> Regards >> Saptarshi >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel