Re: [Rd] R-devel Digest, Vol 83, Issue 2

From: Laurent Gautier <>
Date: Sat, 02 Jan 2010 17:36:53 +0100

[Disclaimer: what is below reflects my understanding from reading the R source, others will correct where deemed necessary]

On 1/2/10 12:00 PM, wrote:
> Hello,
> We are currently making lots of changes to Rcpp (see the open Rcpp
> mailing list if interested [1] in the details).
> We are now using [2] R_PreserveObject and R_ReleaseObject to manage
> garbage collection instead of the PROTECT/UNPROTECT dance. This seems to
> work well, but I was wondering if there was documentation about it.

The most precise technical documentation is in memory.c PROTECT is an alias for Rf_protect, itself an alias for SEXP protect(SEXP s);
and uses a stack (R_PPStack) to store protected objects.

> In particular, if we preserve the same SEXP twice (or more), should we
> implement some sort of reference counting ?

This depends on the requirements for your system.

For example, in rpy2 I added a reference counting layer(*) because I wanted to allow several Python objects to share the same underlying R object, but that's not currently(*) counting how many times an object should be freed.
(*: imperfect, but currently doing a very decent job - details upon request).

That kind of feature could be provided by R's C-level API, since this could be seen of general use as well as give an opportunity to improve the performances of the R_PreservedObject/R_ReleaseObject duo whenever a lot of objects are protected and/or external code is protecting/releasing objects through a FIFO proxy.

> Reading the source (below, from memory.c) I think not, but some
> confirmation would help.

I understand the code in memory.c like an object preserved twice needs to be freed twice: R_PreciousList is just a (linked) list, and "R_PreserveObject(object)" adds the object to the beginning of the list while "R_ReleaseObject(object)" removes the first "object" found from the list.

> void R_PreserveObject(SEXP object)
> {
> R_PreciousList = CONS(object, R_PreciousList);
> }
> static SEXP RecursiveRelease(SEXP object, SEXP list)
> {
> if (!isNull(list)) {
> if (object == CAR(list))
> return CDR(list);
> else
> CDR(list) = RecursiveRelease(object, CDR(list));
> }
> return list;
> }
> void R_ReleaseObject(SEXP object)
> {
> R_PreciousList = RecursiveRelease(object, R_PreciousList);
> }
> I'd also be interested if there is some ideas on the relative efficiency
> of the preserve/release mechanism compared to PROTECT/UNPROTECT.

PROTECT/UNPROTECT is trading granularity for speed. It is a stack with only tow operations possible:
- push 1 object into the stack

- pull (unprotect) N last objects from the stack


> Thanks,
> Romain
> [1]
> [2]
> -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30
> |- : C++ exceptions
> at the R level |- : CPP package: exposing C++ objects
> `- : new package : bibtex mailing list Received on Sat 02 Jan 2010 - 16:41:42 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Sat 02 Jan 2010 - 17:10:10 GMT.

Mailing list information is available at Please read the posting guide before posting to the list.

list of date sections of archive