【问题标题】:What does `retracemem` do in R?`retracemem` 在 R 中做了什么?
【发布时间】:2011-11-11 18:46:07
【问题描述】:

在回答了tracememrecently之后,我了解了retracemem?retracemem 的帮助和其中的例子让我没有开悟。

retracemem 实际上做了什么,为什么?它并没有做我认为它会做的事情,即将一个对象指向另一个对象的内存位置,至少据我所知。

我尝试了像 .Internal(inspect()) 这样的魔法调用,它对我没有任何魔力:

> a = 1:10
> b = a[-1]
> .Internal(inspect(a))
@00000000087AE578 13 INTSXP g0c4 [NAM(2)] (len=10, tl=23336) 1,2,3,4,5,...
> .Internal(inspect(b))
@00000000087AE8E8 13 INTSXP g0c4 [NAM(2)] (len=9, tl=7208) 2,3,4,5,6,...
> retracemem(b,retracemem(a))
> .Internal(inspect(b))
@00000000087AE8E8 13 INTSXP g0c4 [NAM(2)] (len=9, tl=7208) 2,3,4,5,6,...

【问题讨论】:

    标签: r internals


    【解决方案1】:

    我认为 retracemem() 只是让您标记一个变量副本,这不会产生一个 tracemem 语句(例如上面的 b 它实际上只是 a 没有第一个元素的副本),因为从相同的源变量派生,因此您可以继续观察副本/部分副本的传播,并查看它们是从同一源派生的。

    例如,A 的内存是如何被复制/传播的:

    > A <- 1:10
    > tracemem(A)
    [1] "<0x100a2a978>"
    > B <- A                                # Assignment to B doesn't make copy
    > C <- A + 1                            # Assignment to C makes copy, alters it
    tracemem[0x100a2a978 -> 0x1020ebbf0]: 
    > D <- C + 1                            # Assignment to D makes copy, alters it
    tracemem[0x1020ebbf0 -> 0x1020ebc98]: 
    > E <- B + 1                            # Assignment to E makes copy, alters it
    tracemem[0x100a2a978 -> 0x1020a4208]: 
    > F <- A[-1]                            # Assignment to F doesn't make copy?
    > G <- F + 1                            # Even after altering it?
    > retracemem(F, retracemem(A))          # Hint to R that F is really A derived
    tracemem[<0x100a2a978> -> 0x1009c5910]: 
    > G <- F + 1                            # Reassignment to G makes copy, alters it
    tracemem[0x1009c5910 -> 0x1020a4748]: 
    

    但话说回来,我可能完全错了......

    【讨论】:

    • 我一定很密集。我的一种解释是,当分配 G 时没有打印任何消息这一事实表明 F 的分配破坏了跟踪。后来,在我看来,tracememretracemem 在执行第二个 G 分配时都会给出相同的后续行为。在这种情况下,它们看起来是一样的。我不确定在这种情况下我们如何从retracemem 中受益。一定有我遗漏的东西。
    • 我查看了do_tracemem()do_retracemem() 的来源。他们之间似乎没有太大的区别。 do_retracemem() 标记要跟踪的新对象(与do_tracemem() 相同),然后吐出一行显示新对象和前一个对象之间的链接,然后打印出我假设的函数列表在堆栈上调用(除非你在函数调用中调用了retracemem(),否则你看不到这一点)。我认为它只是在您想在不确定的情况下链接内存使用来源时的一座桥梁。
    • 我也查看了代码(在debug.c,对吗?),并得出了类似的结论。当代码未记录和未注释时,我喜欢它。虽然这个小评论很有趣:/* FIXME: ... - 我认为这是一个无害的问题,但它最初很引人注目。感谢您抽出宝贵时间查看此内容并提供见解。
    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 2010-10-26
    相关资源
    最近更新 更多