[Rcpp-devel] Garbage collection PreserveObject.

Romain Francois francoisromain at free.fr
Sun Jan 24 18:38:55 CET 2010

On 01/24/2010 05:13 PM, Guillaume Yziquel wrote:
> Romain Francois a écrit :
>> On 01/24/2010 12:44 AM, Guillaume Yziquel wrote:
>>> Hi.
>>> I recently noticed that the garbage-collection interfacing toping has
>>> been quite active at the beginning of the month on this list, so I'm
>>> asking here. My question concerns essentially my OCaml binding, but I'll
>>> try to make it as language agnostic as possible to somehow stay within
>>> the scope of this list.
>> Here are some axioms:
>> - when you PROTECT, you must UNPROTECT.
>> - when you R_PreserveObject, you should R_ReleaseObject
>> - both approach are unrelated
> So far, so good.
>>> Two questions:
>>> -1- From what I gathered, it is fine to issue two PreserveObject
>>> statements on the same SEXP, and then two ReleaseObject afterwards. It
>>> seemed to me that reference counting was not needed, from my
>>> understanding of the past discussion. Am I wrong?
>> R_Preserve/R_Release are based on a precious pair list. when you
>> R_Preserve an object, say "x", then x is added in front of the
>> pairlist (there is no check to see if the object is already in the
>> pairlist).
>> when you release, it goes though the pairlist until it finds the
>> target SEXP (the first time) and removes it.
> Wow! So if I use a huge datastructure, and split it up brutally to otain
> many SEXPs, for instance a bing number N, then the release time is in
> O(N^2)? That's crazy!

Why would you want to do this particular thing is an enigma to me. In 
any case, you can create a generic vector (VECSXP) and stuff your N 
objects there, and then you Preserve/Release this vector.

>> so it is not really reference counting, but the only thing you have to
>> do is release as many times as you protect (in whatever order you
>> choose, whenever you choose)
> In my situation, writing an interface that chains the two garbage
> collectors with such a runtime penalty is simply inadequate. It will
> work, but it would be wrong to do so.
>>> -2- Once you have, in your C/C++ code, obtained a pointer to a SEXP from
>>> R, do you need to PROTECT it, then do a PreserveObject, then UNPROTECT
>>> it? Or is PreserveObject simply fine? (I guess so, but I'm damn unsure).
>> They are totally unrelated.
> Even if your C code is multithreaded? Isn't it better to PROTECT, then
> PreserveObject, then UNPROTECT? To avoid an R garbage collection between
> the protected allocation and the PreserveObject stuff that comes after.

No idea, please ask such questions to R-devel, not that I want to be 
harsh, I just don't know.

If I wanted to do something multithreaded I would definitely rule ourt 
PROTECT/UNPROTECT because it is basically a stack, and it requires you 
to balance things.

I'd probably go for a "precious list" per threadkind of thing. (but 
again I have not programmed with threads outside of java, where this is 

> But in a multithreaded setting, does UNPROTECT make sense? Won't it
> potentially unprotect the wrong R value depending on the order threads
> make requests to the protection stack?
>> As simon said on R-devel, it just is not a matter of choice. If you
>> want your object to persist you use Preserve/Release. If your SEXP is
>> local to function, then PROTECT/UNPROTECT will work "faster" ...
>> however you can still use Preserve/Release for local objects.
> Still, the performance penalty for simply interfacing garbage collectors
> is rather high...
>> Essentially, in Rcpp we only use Preserve/Release so that garbage
>> collection management is implicit, automatic and hidden.
>> Does that help ?
> Yes very much. At least, it is a clear solution.
>> Romain
> All the best,

Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
|- http://tr.im/KfKn : Rcpp 0.7.2
|- http://tr.im/JOlc : External pointers with Rcpp
`- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009

More information about the Rcpp-devel mailing list