[Rd] Objects not gc'ed due to caching (?) in R's S3 dispatch mechanism
luke-tierney at uiowa.edu
luke-tierney at uiowa.edu
Thu Mar 29 17:37:06 CEST 2018
Now also committed to the release branch.
Best,
luke
On Tue, 27 Mar 2018, luke-tierney at uiowa.edu wrote:
> 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