[Rd] Objects not gc'ed due to caching (?) in R's S3 dispatch mechanism

luke-tierney at uiowa.edu luke-tierney at uiowa.edu
Tue Mar 27 15:22:41 CEST 2018


I have committed a change to R-devel that addresses this. To be on the
safe side I need to run some more extensive tests before deciding if
this can be ported to the release branch for R 3.5.0. Should know in a
day or two.

Best,

luke

On Tue, 27 Mar 2018, luke-tierney at uiowa.edu wrote:

> This has nothing to do with printing or dispatch per se. It is the
> result of an internal register (R_ReturnedValue) being protected. It
> gets rewritten whenever there is a jump, e.g. by an explicit return
> call. So a simplified example is
>
> new_foo <- function() {
>  e <- new.env()
>    reg.finalizer(e, function(e) message("Finalizer called"))
>      e
>      }
>
> bar <- function(x) return(x)
>
> bar(new_foo())
> gc() # still in .Last.value
> gc() # nothing
>
> UseMethod essentially does a return call so you see the effect there.
>
> The R_ReturnedValue register could probably be safely cleared in more
> places but it isn't clear exactly where. As things stand it will be
> cleared on the next use of a non-local transfer of control, and those
> happen frequently enough that I'm not convinced this is worth
> addressing, at least not at this point in the release cycle.
>
> Best,
>
> luke
>
> On Mon, 26 Mar 2018, Iñaki Úcar wrote:
>
>> Hi,
>> 
>> I initially opened an issue in the R6 repo because my issue was with
>> an R6 object. But Winston (thanks!) further simplified my example, and
>> it turns out that the issue (whether a feature or a bug is yet to be
>> seen) had to do with S3 dispatching.
>> 
>> The following example, by Winston, depicts the issue:
>> 
>> print.foo <- function(x, ...) {
>>  cat("print.foo called\n")
>>  invisible(x)
>> }
>> 
>> new_foo <- function() {
>>  e <- new.env()
>>  reg.finalizer(e, function(e) message("Finalizer called"))
>>  class(e) <- "foo"
>>  e
>> }
>> 
>> new_foo()
>> gc() # still in .Last.value
>> gc() # nothing
>> 
>> I would expect that the second call to gc() should free 'e', but it's
>> not. However, if we call now *any* S3 method, then the object can be
>> finally gc'ed:
>> 
>> print(1)
>> gc() # Finalizer called
>> 
>> So the hypothesis is that there is some kind of caching (?) mechanism
>> going on. Intended behaviour or not, this is something that was
>> introduced between R 3.2.3 and 3.3.2 (the first succeeds; from the
>> second on, the example fails as described above).
>> 
>> Regards,
>> Iñaki
>> 
>> PS: Further discussion and examples in 
>> https://github.com/r-lib/R6/issues/140
>> 
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>> 
>
>

-- 
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   luke-tierney at uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


More information about the R-devel mailing list