roots.Rd
These functions return useful starting points to supply to
mem_snapshot()
.
root_ns_registry()
returns R's namespace registry as a list. It
contains all the namespaces currently loaded in the R session.
root_cpp11()
returns the precious list of cpp11. This is a
doubly linked list preserved in R's own precious list.
root_precious_list()
returns R's precious list. However this
requires a custom build of R where R_PreciousList
is exposed as a
non-static symbol.
root_cpp11()
root_ns_registry()
The R precious list is (as currently implemented) a pairlist of
objects currently protected via the C API function
R_PreserveObject()
. Preserved objects are stored in this pairlist
until a corresponding R_ReleaseObject()
call is performed. Some
objects are meant to be preserved for the whole duration of the R
session (global caches), others are preserved for a limited
duration. It may happen that R_ReleaseObject()
is not being
called when it should. This causes a memory leak via the precious
list.
R currently does not provide an easy way to get the precious list.
So you will need to either patch R to expose it (e.g. remove its
static
qualifier) so that you can call root_precious_list()
, or
run R though a debugger like gdb
or lldb
.
If you choose to use a debugger, use p
to print the address of
the list:
p R_PreciousList
#> (SEXP) $0 = 0x000000010107cf58
Copy that address in an R string and dereference it with
deref()
:
prec <- deref("0x000000010107cf58")
Avoid printing the precious list in the console because it contains a large amount of data, such as the global cache for the global environment and attached packages.
Some things to consider while working with the precious list:
If you record a snapshot of the precious list, beware that
objects in the global environment will be reachable through the
global cache. These objects are normally excluded from
snapshots. You can exclude an object from the snapshot by
stashing it with mem_stash()
.
If you take before and after snapshots, make sure to capture the
R_PreciousList
address each time. The precious list is
currently implemented as a stack of pairlist nodes. If you don't
refresh the pointer you will miss all new elements added on the
top of the stack.