201

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?

2
  • In addition to all answer, I would like to refer reading memory management from Advanced R: adv-r.had.co.nz/memory.html Commented Apr 1, 2021 at 4:06
  • 1
    This answer from a different but related question, in contrast to answers here, gives sorted AND human readable output. Commented Mar 11, 2024 at 13:12

9 Answers 9

270

some time ago I stole this little nugget from here:

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

it has served me well

Sign up to request clarification or add additional context in comments.

13 Comments

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")
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) ) .
@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?
you can also use format to get human readable sizes: sort(sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto')))
@savagent that's right, according to adv-r.had.co.nz/memory.html
|
66

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

2 Comments

Useful to print in a human readable way: print(object.size(my_object), units = "auto") or format(object.size(my_object), units = "auto")
"memory.size() is no longer supported." R version 4.3.1, Windows 11, March 2024.
26

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> 

Comments

19

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)

1 Comment

The third line can be easily sorted with dplyr like so: subset(ll(), KB > 1000) %>% arrange(desc(KB))
7

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)

Comments

3

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

...

Comments

1

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

Comments

1

I've used the solution from this link

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

Works fine!

Comments

-1

I wanted a solution like JD Long's but that auto formatted the units and sorted the results. There were a few suggestions in the comments, but none of them actually worked so I came up with this.

getMemUsage = function()
{
  #get sizes formatted for printing 
  sizesToPrint=sapply(ls(name=".GlobalEnv"), function(x) format(object.size(get(x)), unit = 'auto')) 
    
  #get raw sizes in bytes, sort decending, match names to get sorted printing order for formatted results
  idx = match(names(sort(sapply(ls(name=".GlobalEnv"), function(x) object.size(get(x))),decr=T)), names(sizesToPrint))
  
  print(sizesToPrint[idx])

  #Print total usage in Mb
  cat("\nTotal: ")
  print(object.size(x=lapply(ls(name=".GlobalEnv"), get)), unit='Mb')
}

Example output:

getMemUsage()
   featuresd           df        parad          plt         cplt      scoresd          reg          pts          tmp       lscale       pscale          fts          fTs          idx 
  "173.4 Mb"   "157.2 Mb"    "11.6 Mb"     "6.5 Mb"     "6.4 Mb"     "5.4 Mb"     "4.1 Mb"       "1 Mb"   "131.5 Kb"     "130 Kb"     "130 Kb"    "74.5 Kb"    "74.5 Kb"    "65.2 Kb" 
        sntf          stf          stp         idx2  getMemUsage           ma         cars         peek sizesToPrint        count            i 
   "65.2 Kb"    "65.2 Kb"    "65.2 Kb"      "53 Kb"    "15.4 Kb"     "8.5 Kb"       "7 Kb"     "6.4 Kb"     "3.1 Kb"   "56 bytes"   "56 bytes" 

Total: 366.4 Mb

Or if you prefer ungodly oneliners:

#using one variable as a side effect: sizesToPrint
sizesToPrint=sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto')); sizesToPrint[match(names(sort(sapply(ls(), function(x) object.size(get(x))),decr=T)), names(sizesToPrint))]; cat("\nTotal: "); print(object.size(x=lapply(ls(name=".GlobalEnv"), get)), unit='Mb')

#sideffect free 
sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto'))[match(names(sort(sapply(ls(), function(x) object.size(get(x))),decr=T)), names(sapply(ls(), function(x) format(object.size(get(x)), unit = 'auto'))))]; cat("\nTotal: "); print(object.size(x=lapply(ls(name=".GlobalEnv"), get)), unit='Mb')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.