确定对象的内存使用情况?

191

我想知道当前工作空间中每个对象使用了多少内存。是否有简单的方法可以实现?


除了所有的答案,我想提供一个阅读《Advanced R》中有关内存管理的链接:http://adv-r.had.co.nz/memory.html - Dr Nisha Arora
8个回答

261

一段时间以前,我从这里偷了这个小技巧:

sort( sapply(ls(),function(x){object.size(get(x))})) 

它一直为我服务得很好。


24
如果想要获取 R 会话所使用的总内存,可以执行 object.size(x=lapply(ls(), get))print(object.size(x=lapply(ls(), get)), units="Mb") - tflutre
4
那个漂亮的小块状物让我误解了,因为我有一个名为“x”的大东西(提示:它看起来很小);这里是替代品:“sort( sapply(mget(ls()),object.size) )”。 - petrelharp
2
我的理解是,这种情况可能会误导人,因为R是写时复制的。如果我执行 some_list <- some_other_list,那么 some_list 的大小将报告为与 some_other_list 相同的大小,但如果我只从 some_list 中读取数据,则内存是共享的。有人能否确认这是否正确? - savagent
15
你也可以使用 format 函数来获取易读的大小:sort(sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto'))). - flying sheep
3
@savagent没错,根据http://adv-r.had.co.nz/memory.html。 - Dzmitry Lazerka
显示剩余6条评论

61

1. 按对象大小

要按对象逐个进行内存分配,请调用object.size()并传入感兴趣的对象:

object.size(My_Data_Frame)

(除非传入的参数是一个变量,否则必须加引号,或者用get调用进行包装。)如果是变量名,则省略引号。

您可以循环遍历命名空间并获取其中所有对象的大小,如下所示:

for (itm in ls()) { 
    print(formatC(c(itm, object.size(get(itm))), 
        format="d", 
        big.mark=",", 
        width=30), 
        quote=F)
}

2. 按对象类型

要按对象类型获取您的命名空间的内存使用情况,请使用memory.profile()

memory.profile()

   NULL      symbol    pairlist     closure environment     promise    language 
      1        9434      183964        4125        1359        6963       49425 
special     builtin        char     logical     integer      double     complex 
    173        1562       20652        7383       13212        4137           1 

还有一个函数memory.size(),但我听说和读过它似乎只在Windows上工作。它只返回一个以MB为单位的值;所以要获取会话中任何时候使用的最大内存,请使用memory.size(max=T)。


5
方便阅读的打印方式:print(object.size(my_object), units = "auto")format(object.size(my_object), units = "auto") - Valentin_Ștefan

24

你可以尝试使用这个问题中介绍的lsos()函数:

R> a <- rnorm(100)
R> b <- LETTERS
R> lsos()
       Type Size Rows Columns
b character 1496   26      NA
a   numeric  840  100      NA
R> 

18

这个问题以前已经发布并且得到了合理的答案,但是我想让您知道另一个有用的方法,使用一个名为gdata和它的ll()函数来获取对象的大小。

library(gdata)
ll() # return a dataframe that consists of a variable name as rownames, and class and size (in KB) as columns
subset(ll(), KB > 1000) # list of object that have over 1000 KB
ll()[order(ll()$KB),] # sort by the size (ascending)

第三行可以使用dplyr轻松排序,如下所示:subset(ll(), KB > 1000) %>% arrange(desc(KB)) - bshor

5

可以使用 dplyr 这个工具来获得一个稍微美观一点的选项。

    data.frame('object' = ls()) %>% 
      dplyr::mutate(size_unit = object %>%sapply(. %>% get() %>% object.size %>% format(., unit = 'auto')),
                    size = as.numeric(sapply(strsplit(size_unit, split = ' '), FUN = function(x) x[1])),
                    unit = factor(sapply(strsplit(size_unit, split = ' '), FUN = function(x) x[2]), levels = c('Gb', 'Mb', 'Kb', 'bytes'))) %>% 
      dplyr::arrange(unit, dplyr::desc(size)) %>% 
      dplyr::select(-size_unit)

2
一个data.table函数,用于将内存和单位分开以便更容易排序。
    ls.obj <- {as.data.table(sapply(ls(),
    function(x){format(object.size(get(x)),
    nsmall=3,digits=3,unit="Mb")}),keep.rownames=TRUE)[,
    c("mem","unit") := tstrsplit(V2, " ", fixed=TRUE)][,
    setnames(.SD,"V1","obj")][,.(obj,mem=as.numeric(mem),unit)][order(-mem)]}

ls.obj

                       obj     mem unit
    1:                obj1 848.283   Mb
    2:                obj2  37.705   Mb

...


0

我已经使用了这个链接的解决方案。

for (thing in ls()) { message(thing); print(object.size(get(thing)), units='auto') }

运行良好!


0
这是一个基于 tidyverse 的函数,用于计算您环境中所有对象的大小:
weigh_environment <- function(env){
  
  purrr::map_dfr(env, ~ tibble::tibble("object" = .) %>% 
                   dplyr::mutate(size = object.size(get(.x)),
                                 size = as.numeric(size),
                                 megabytes = size / 1000000))
  
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接