[Rcpp-devel] Garbage collection PreserveObject.

Guillaume Yziquel guillaume.yziquel at citycable.ch
Sun Jan 24 17:13:29 CET 2010

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!

> 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.

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,

      Guillaume Yziquel

More information about the Rcpp-devel mailing list