9

Program 1:

 library(pryr)

 for (x in 1:3) {
     print(c(address(x), refs(x)))
 }

Output e.g.:

[1] "0x7a6a6c8" "1"        
[1] "0x7a6a6c8" "1"        
[1] "0x7a6a6c8" "1"

Program 2:

library(pryr)

for (x in 1:3) {
  print(c(address(x), refs(x)))
  print(x)
}

Output e.g.:

[1] "0x7ae0298" "1"        
[1] 1
[1] "0x7ae88c8" "1"        
[1] 2
[1] "0x7af2668" "1"        
[1] 3

Obviously the value of x is changing in Program 2, but why is the adress changing too? Can this lead to memory leaks when having a for loop running about 500,000,000 times while the gc is not called during the loop?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Wipster
  • 1,510
  • 1
  • 15
  • 32
  • 2
    If you run an R loop with 5e8 iterations you should worry about performance and not memory leaks (there are none). – Roland Sep 28 '16 at 11:49
  • 2
    What is your R version? Unless the looping variable is used/assigned somewhere, R avoids re-allocating. E.g. compare `for(x in 1:3) { .Internal(inspect(x)) }` VS `for(x in 1:3) { (function(val) val)(x); .Internal(inspect(x)) }`. (Calling a simple closure on "x", marks "x" as multi-referenced) – alexis_laz Sep 28 '16 at 11:57
  • I use version 3.3.1, I'm going to edit the outputs to also give the number of references. – Wipster Sep 28 '16 at 11:59
  • 4
    "x" is marked as multi-referenced _after_ the call to `print` -- `for (x in 1:3) { print(c(address(x), refs(x))); print(x); print(refs(x)); cat("\n\n") }` Each time the loop restarts, a new "x" is allocated (since it was marked by `print` as having >1 references) and its references reset. – alexis_laz Sep 28 '16 at 12:10
  • Ah okay thanks, I got it. Why not make it an answer? – Wipster Sep 28 '16 at 12:30

1 Answers1

2

Having print(x) at the end of the loop marks it as multi-reference, as @alexis_laz mentioned. Since R is a dynamic language, this can happen easily. To test the effects of this, we can print the output of refs(x), print(x), refs(x):

for (x in 1:3) {
  print(refs(x))
  print(x)
  print(refs(x)); cat("\n")
}

Output:

[1] 1
[1] 1
[1] 2

[1] 1
[1] 2
[1] 2

[1] 1
[1] 3
[1] 2
www
  • 4,124
  • 1
  • 11
  • 22