188

I'd like to work out how much RAM is being used by each of my objects inside my current workspace. Is there an easy way to do this?

smci
  • 32,567
  • 20
  • 113
  • 146
Josh Reich
  • 6,477
  • 5
  • 28
  • 26
  • In addition to all answer, I would like to refer reading memory management from Advanced R: http://adv-r.had.co.nz/memory.html – Dr Nisha Arora Apr 01 '21 at 04:06

8 Answers8

256

some time ago I stole this little nugget from here:

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

it has served me well

JD Long
  • 59,675
  • 58
  • 202
  • 294
  • 23
    also, if one wants the total memory used by an R session, one can do `object.size(x=lapply(ls(), get))` and `print(object.size(x=lapply(ls(), get)), units="Mb")` – tflutre Feb 27 '13 at 03:09
  • 4
    That nice little nugged misled me, since I had something big called 'x' (hint: it looked small); here's an replacement: `sort( sapply(mget(ls()),object.size) )` . – petrelharp Aug 28 '14 at 19:58
  • 1
    @tflutre My understanding is that this sort of thing can be misleading as R is copy on write. If I take some_list <- some_other_list, the size of some_list is reported as the same size as some_other_list, but if I only read from some_list then the memory is being shared. Can someone confirm if this is correct? – savagent Sep 25 '14 at 01:42
  • @savagent I don't know enough about R to answer with certainty, but you may well be right. In that case, maybe `memory.profile()` advocated by @doug below is a better solution? You can't distinguish per object anymore, though. – tflutre Sep 25 '14 at 09:20
  • 13
    you can also use `format` to get human readable sizes: `sort(sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto')))` – flying sheep Sep 07 '15 at 14:17
  • Just wanted to note (I know this is old) that you can use `eval` to create this code as a function, set the 2nd argument to `parent.frame()` and just feed `ls()` into the overall function. – giraffehere Dec 03 '15 at 16:49
  • 2
    @savagent that's right, according to http://adv-r.had.co.nz/memory.html – Dzmitry Lazerka Jan 03 '16 at 20:46
  • 1
    Isn't there a more efficient solution that doesn't make a copy of all the objects in ls() in order to get memory usage, which `get()` seems to be doing here? – altabq Feb 15 '16 at 21:52
  • 2
    I think using `magrittr` is a little cleaner. Can do `Mb <- ls() %>% sapply(. %>% get %>% object.size %>% '/'(10^6))` then `cbind(Mb, "Mb") %>% as.data.frame` – Danton Noriega Mar 26 '16 at 22:10
  • Same same, but slightly different. It is also possible to modify/mask normal print.object_size with this oneliner `print.object_size = function(x) utils:::print.object_size(x,units="Mb") ` If this defined function is in scope, then object.size will output in unit Mb always – Soren Havelund Welling Nov 04 '19 at 14:55
61

1. by object size

to get memory allocation on an object-by-object basis, call object.size() and pass in the object of interest:

object.size(My_Data_Frame)

(unless the argument passed in is a variable, it must be quoted, or else wrapped in a get call.)variable name, then omit the quotes,

you can loop through your namespace and get the size of all of the objects in it, like so:

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

2. by object type

to get memory usage for your namespace, by object type, use 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 

(There's another function, memory.size() but i have heard and read that it only seems to work on Windows. It just returns a value in MB; so to get max memory used at any time in the session, use memory.size(max=T)).

doug
  • 69,080
  • 24
  • 165
  • 199
  • 5
    Useful to print in a human readable way: `print(object.size(my_object), units = "auto")` or `format(object.size(my_object), units = "auto")` – Valentin_Ștefan Jan 17 '19 at 14:55
24

You could try the lsos() function from this question:

R> a <- rnorm(100)
R> b <- LETTERS
R> lsos()
       Type Size Rows Columns
b character 1496   26      NA
a   numeric  840  100      NA
R> 
Community
  • 1
  • 1
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
18

This question was posted and got legitimate answers so much ago, but I want to let you know another useful tips to get the size of an object using a library called gdata and its ll() function.

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)
Blaszard
  • 30,954
  • 51
  • 153
  • 233
  • The third line can be easily sorted with dplyr like so: subset(ll(), KB > 1000) %>% arrange(desc(KB)) – bshor Aug 04 '21 at 20:04
5

another (slightly prettier) option using 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)
filups21
  • 1,611
  • 1
  • 19
  • 22
2

A data.table function that separates memory and unit for easier sorting:

    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

...

Rohit Gupta
  • 4,022
  • 20
  • 31
  • 41
rferrisx
  • 1,598
  • 2
  • 12
  • 14
0

Here's a tidyverse-based function to calculate the size of all objects in your environment:

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))
  
}

CGP
  • 129
  • 8
0

I've used the solution from this link

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

Works fine!

TheNewGuy
  • 161
  • 1
  • 3