Skip to content
Prev 54986 / 63424 Next

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

I'd like to emphasize that although I?aki's example uses print(), it
also happens with other S3 generics. Please note that each of the
following examples might need to be run in a clean R session to work.

===========
Here's an example that doesn't use S3 dispatch. The finalizer runs correctly.

ident <- function(x) invisible(x)

env_with_finalizer <- function() {
  reg.finalizer(environment(), function(e) message("Finalizer called"))
  environment()
}

ident(env_with_finalizer())
gc() # Still in .Last.value
gc() # Finalizer called


===========
Here's an example that uses S3. In this case, the finalizer doesn't run.

ident <- function(x) UseMethod("ident")
ident.default <- function(x) invisible(x)

env_with_finalizer <- function() {
  reg.finalizer(environment(), function(e) message("Finalizer called"))
  environment()
}

ident(env_with_finalizer())
gc()
gc() # Nothing

However, if the S3 generic is called with another object, the
finalizer will run on the next GC:

ident(1)
gc() # Finalizer called

===========

This example is the same as the previous one, except that, at the end,
instead of calling the same S3 generic on a different object (that is,
ident(1)), it calls a _different_ S3 generic on a different object
(mean(1)).

ident <- function(x) UseMethod("ident")
ident.default <- function(x) invisible(x)

env_with_finalizer <- function() {
  reg.finalizer(environment(), function(e) message("Finalizer called"))
  environment()
}

ident(env_with_finalizer())
gc()
gc() # Nothing

# Call a different S3 generic
mean(1)
gc() # Finalizer called


-Winston
On Mon, Mar 26, 2018 at 4:46 PM, I?aki ?car <i.ucar86 at gmail.com> wrote: