rmemoryshinyram

How to make Shiny give back memory after a session ends?


I have a shiny app that allows each user to select which data set to load. Everything in the app works wonderful, except for memory usage. After the session is ended and the user closes the web browser, Shiny does not give back the free memory to the machine it is running on. Eventually, after accessing it enough times, it runs out of memory.

In traditional R, I often take care of this with frequent calls to gc() after removing data. However, that does not seem to work in my shiny app.

Hours of googling has not rendered anything insightful. Is there a clean way of freeing up unused memory in this scenario?


Solution

  • Maybe you can gc() under observe statement with invalidateLater? Also maybe you can limit each session to some memory threshold or some timeout if possible? Below you can see how much memory you are taking for each session. Also look at your Task Manager in the Processes how much this process takes in (note: current example takes about 440Mb per session)

    rm(list = ls())
    library(shiny)
    
    cleanMem <- function(n=10) { for (i in 1:n) gc() }
    
    runApp(list(
      ui = fluidPage(
        tableOutput('foo')
      ),
      server = function(input, output,session) {
        
        observe({
          # periodically collect
          invalidateLater(1000,session)
          cleanMem()
        })
    
        x1 <- 1:100000000
        x2 <- rbind(mtcars, mtcars)
        env <- environment()  # can use globalenv(), parent.frame(), etc
        output$foo <- renderTable({
          data.frame(
            object = ls(env),
            size = unlist(lapply(ls(env), function(x) {
              object.size(get(x, envir = env, inherits = FALSE))
            }))
          )
        })
      }
    ))