This is a follow up to a previous question here on storing and retrieving matrices in memory using xptr - which was fantastically answered - thank you very much. Now that I can create and retrieve matrices in memory using xptr how do I properly finalize/destroy the object. Rcpp objects should be automatically garbage collected on deletion but when I create the pointer, if I delete it in R I have to run gc() twice to recover the memory e.g.
// This function wraps the matrix an returns a pointer
// [[Rcpp::export]]
SEXP writeMemObject(NumericMatrix mat)
{
XPtr<NumericMatrix> ptr(new NumericMatrix(mat), true);
return ptr;
}
The function to retrieve the matrix (from previous answer)
// [[Rcpp::export]]
NumericMatrix getMemObject(SEXP ptr)
{
XPtr<NumericMatrix> out(ptr);
return *out;
}
Then in R
createMemMatrix <- function(dims){
ptr <- writeMemObject(matrix(runif(prod(dims)), nc = dims[2]))
return(ptr)
}
ptr <- createMemMatrix(c(1e4, 1e4))
#mat <- getMemObject(ptr) # this works but not run here
rm(ptr);
gc(); # nothing seems to happen in memory
gc(); # memory is freed (visible in system monitor)
The bigmemory
R package was mentioned in the answer to the previous question and their objects are memory freed right away
# In R
require(bigmemory)
# be careful this is a large matrix
x1 <- big.matrix(ncol = 1e4, nrow = 1e4)
x1[,] <- runif(1e8)
rm(x1)
gc() # memory is freed right away (visible on system monitor)
I have tried a similar method used in the bigmemory
package and I to register the pointer when I create it:
// C function for destroying the matrix behind the pointer
void destroyItem(SEXP ptr)
{
NumericMatrix *pm=(NumericMatrix*)(R_ExternalPtrAddr(ptr));
delete pm;
R_ClearExternalPtr(ptr);
}
// This function wraps the matrix an returns a pointer
// [[Rcpp::export]]
SEXP writeMemObject(NumericMatrix mat)
{
XPtr<NumericMatrix> ptr(new NumericMatrix(mat), true);
R_RegisterCFinalizerEx(ptr, (R_CFinalizer_t) destroyItem, (Rboolean) TRUE);
return ptr;
}
But this does not make a difference. The bigmemory
package is great but I think it is worth doing this using Rcpp objects because a wide range of objects can be stored in memory.