【问题标题】:Why is the address of a loop variable changing when using it?为什么循环变量的地址在使用时会发生变化?
【发布时间】:2017-02-06 09:03:38
【问题描述】:

方案一:

 library(pryr)

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

输出例如:

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

方案二:

library(pryr)

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

输出例如:

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

很明显 x 的值在程序 2 中发生了变化,但为什么地址也发生了变化?如果在循环期间不调用 gc,则当 for 循环运行大约 500,000,000 次时,这会导致内存泄漏吗?

【问题讨论】:

  • 如果您使用 5e8 次迭代运行 R 循环,您应该担心性能而不是内存泄漏(没有)。
  • 你的 R 版本是多少?除非循环变量在某处使用/分配,否则 R 会避免重新分配。例如。比较for(x in 1:3) { .Internal(inspect(x)) }for(x in 1:3) { (function(val) val)(x); .Internal(inspect(x)) }。 (在“x”上调用一个简单的闭包,将“x”标记为多引用)
  • 我使用的是 3.3.1 版本,我将编辑输出以同时给出引用的数量。
  • "x" 被标记为多引用调用print -- for (x in 1:3) { print(c(address(x), refs(x))); print(x); print(refs(x)); cat("\n\n") } 每次循环重新启动时,都会分配一个新的“x”(因为它被 print 标记为具有 >1 个引用)并且它的引用被重置。
  • 嗯,好的,谢谢,我明白了。为什么不让它成为一个答案?

标签: r for-loop memory pryr


【解决方案1】:

正如@alexis_laz 所提到的,在循环末尾有 print(x) 将其标记为多引用。由于 R 是一种动态语言,这很容易发生。为了测试这个效果,我们可以打印 refs(x), print(x), refs(x) 的输出:

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

输出:

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

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

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

【讨论】:

    猜你喜欢
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多