R的内存管理 6

当大数据量到来的时候,使用R分析会显得力不从心,最主要的问题在于内存。因为在大多数情况下,R需要将数据全部读入内存,然后再将数据做为一个整体对象来处理。同时,R的一些数据结构本身也需要大量的内存,比如list。一些数据读入R后,会占用几倍甚至几十倍的内存,比如将一个bigwig文件import成GRanges对象。

R的内存管理和java类似的,使用了Garbage collection。但是垃圾回收从来都不是主动的,也不是定期的,它只在R认为它需要更多的内存的时候才会发生。
Garbage collection normally happens lazily: R calls gc() when it needs more space. In reality, that R might hold onto the memory after the function has terminated, but it will release it as soon as it’s needed。

在处理大数据时,尤其是循环操作时,一定要养成先检查内存的习惯,否则内存耗尽时也是你前功尽弃之时。

有很多小程序可以帮助我们方便地查看当前的内存占用情况,比如:

##  http://adv-r.had.co.nz/memory.html#garbarge-collection
mem <- function() {
  bit <- 8L * .Machine$sizeof.pointer
  if (!(bit == 32L || bit == 64L)) {
    stop("Unknown architecture", call. = FALSE)
  }
 
  node_size <- if (bit == 32L) 28L else 56L
 
  usage <- gc()
  sum(usage[, 1] * c(node_size, 8)) / (1024 ^ 2)
}
 
## http://stackoverflow.com/questions/1358003/tricks-to-manage-the-available-memory-in-an-r-session
# improved list of objects
.ls.objects <- function (pos = 1, pattern, order.by,
                        decreasing=FALSE, head=FALSE, n=5) {
    napply <- function(names, fn) sapply(names, function(x)
                                         fn(get(x, pos = pos)))
    names <- ls(pos = pos, pattern = pattern)
    obj.class <- napply(names, function(x) as.character(class(x))[1])
    obj.mode <- napply(names, mode)
    obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
    obj.size <- napply(names, object.size)
    obj.dim <- t(napply(names, function(x)
                        as.numeric(dim(x))[1:2]))
    vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
    obj.dim[vec, 1] <- napply(names, length)[vec]
    out <- data.frame(obj.type, obj.size, obj.dim)
    names(out) <- c("Type", "Size", "Rows", "Columns")
    if (!missing(order.by))
        out <- out[order(out[[order.by]], decreasing=decreasing), ]
    if (head)
        out <- head(out, n)
    out
}
# shorthand
lsos <- function(..., n=10) {
    .ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}

了解了当前的内存占用情况,对占用过多内存或者暂时不用的对象进行处理。最简单的办法就是保存或者删除这些对象。删除我们使用rm函数。在删除之后,R是不会释放内存的,需要通过调用

gc(reset=TRUE)

来要求系统回收垃圾。

了解R的处理过程也会帮助我们减少内存的使用量。比如数据可以保存为integer的时候就尽量避免使用double类型。在使用循环时,最好事先分配好内存,而不是使用类似A <- c(A, otherElement)这种方式在过程中重新分配内存。

6 thoughts on “R的内存管理

  1. Reply Shi Junfeng 5月 1,2014 2:13 上午

    一直在拜读您的这个博客,也发现跟您的境遇很相似,我也是在关西读的硕士,不过没能申请上美国的学校,于是继续留在关西读博了。。。也同样跟您类似地利用R进行DE研究,谢谢您的博客给我带来的众多启发和帮助。现在最困惑的点在于R的作图,图片边上余白以及注释和图片位置的分配,不知道您是否有一些推荐的对于R作图的相关资料或者如果练习,现在是自己可以做出来结果,但是没法很漂亮的展现出来或者按照自己设想的布局来去配置,par()函数之类的总是容易搞混。。。

    • Reply admin 5月 1,2014 7:49 上午

      您可以试用一下grid或者ggplot2,前者是R的核心包,可以直接调用。熟悉了viewport,您可以随心所欲地安排布局了。您在日本哪个学校?

  2. Reply Shi Junfeng 5月 1,2014 9:26 下午

    学生现在在京都大学,读药学方向,如果关西在这边能帮上您什么,请您尽管开口,您无形之中给了我很多帮助,所以也想可以做些什么来回馈您。再次感谢~~

Leave a Reply

  

  

  

%d 博主赞过: