R Fuga de memoria brillante: ¿sugerencias sobre cómo encontrarla?

Estoy buscando ideas generales sobre cómo identificar las fugas de memoria en un programa brillante para R. Estoy luchando por identificar exactamente de dónde proviene la fuga, por lo que es difícil de recrear, y mi código ya supera las 1000 líneas. Estoy seguro de que está relacionado con observar y observar eventos, pero no puedo precisarlo exactamente. De hecho, me gustó la idea propuesta aquí por bborgeser, usando las opciones, reactlog:https: //github.com/rstudio/shiny/issues/159 Pero cuando lo intento, el showReactLog () no se carga. Supongo que mi código es demasiado grande para eso.

Entonces mi pregunta principal, ¿cuál es la mejor manera de identificar una pérdida de memoria? Estoy usando el paquete pryr para rastrear la memoria utilizada después de cada envío. Entonces puedo decir que la memoria está aumentando. Encontré algunos otros artículos sobre pérdidas de memoria, pero están más relacionados con problemas específicos para resolver, en lugar de una pregunta general:https: //github.com/rstudio/shiny/issues/93

Dado que algunas personas trabajan mejor al ver un código real, intenté hacer todo lo posible para recrearlo de manera más sucinta. Esto lo aumentará aproximadamente .3 mb por. ¿Quizás tenga algo que ver con el uso de listas sobre listas? He estado jugando con mis cosas durante semanas y realmente no estoy haciendo ningún progreso.

En este código específicamente, sé que la pérdida de memoria definitivamente está en Reactivo / Observar. Si los bloqueo, la memoria no aumentará. Pero estoy seguro de que puede usar reactivo y observar sin aumentar la memoria. Entonces, esto me lleva de vuelta a mi pregunta original, en este caso la encontré bloqueando lentamente las secciones, pero incluso cuando lo intento en mi código más grande no puedo identificar de qué sección proviene. Entonces, ¿cómo hace la gente para encontrar sus fugas?

    #Library Load##########################################################################################
lapply(c("shiny","tidyverse","shinydashboard","shinyjs","pryr"),require,character.only = T)
#ui, shiny body#########################################################################################
body<-dashboardBody(
  useShinyjs(),
            ({
              tabs<-lapply(1:length(1:8), function(x){
                tabPanel(box(title = paste0('Tab ',x),  width = NULL),
                fluidPage(
                  div(id = paste0("BOX_",x),
                      column(width = 6, align = "center",
                          lapply(seq(1,15,2),function(y){
                              div(id = paste0("Box_ID_",x,"_",y),
                                  box(width = NULL, title = paste0("Reading",((y/2)+.5)),
                                      column(width = 4,
                                             numericInput(paste0("Number_",x,"_",y), label = paste0("Number - ",y), value = 0, min = 0, max = 60, step = .1)),
                                      column(width = 4,
                                             numericInput(paste0("Number_",x,"_",y+1), label = paste0("Number - ",y+1), value = 0, min = 0, max = 60, step = .1))))
                          })),
                      column(width = 2, align = "center",
                                 actionButton(paste0("Complete_",x),"Complete"))
                  )))
              }) 
              do.call(tabBox, c(tabs, list(width = NULL)))
            }))
##UI combination###################
ui<-dashboardPage(
  dashboardHeader(disable = T),
  dashboardSidebar(disable = T),
  body)
#######Server################
server <- function(input, output, session) {
  #Tab 1 - Reactive Average
  Avg<-reactive({
    lapply(1:8, function(x) {
      lapply(seq(1,15,2),function(y){
        req(input[[paste0("Number_",x,"_",y)]],input[[paste0("Number_",x,"_",y+1)]])
        if(input[[paste0("Number_",x,"_",y)]] == 0 | input[[paste0("Number_",x,"_",y+1)]] == 0) {0} else {
          (input[[paste0("Number_",x,"_",y)]]+input[[paste0("Number_",x,"_",y+1)]])/2}
      })
    })
  })

  #Tab 1 - Show or hide boxes
  lapply(1:8, function(x) {
    lapply(seq(1,15,2),function(y){
      observe({
        req(input[[paste0("Number_",x,"_",y)]],input[[paste0("Number_",x,"_",y+1)]])
        if(y == 1 & Avg()[[x]][[(y/2)+.5]] <= 30) {
          shinyjs::show(paste0("Box_ID_",x,"_",1))
          shinyjs::hide(paste0("Box_ID_",x,"_",3))
        } else if(y == 1 & Avg()[[x]][[(y/2)+.5]] > 30) {
          shinyjs::show(paste0("Box_ID_",x,"_",1))
          shinyjs::show(paste0("Box_ID_",x,"_",3))
        } else if(Avg()[[x]][[(y/2)+.5]] > 30) {
          shinyjs::show(paste0("Box_ID_",x,"_",y+2))
        } else {shinyjs::hide(paste0("Box_ID_",x,"_",y+2))}
      })
    })
  })

  #Tab 1 - Submit Button - Reset boxes, create data frame and append to file. 
  lapply(1:8,function(x){
    observeEvent(input[[paste0("Complete_",x)]],{
     #Reset the page
      reset(paste0("BOX_",x))
      #Garabage collect
      gc()
      #Print memory used. Tracking memory leaks
      print(mem_used())
    })
  })
}
shinyApp(ui, server)

Respuestas a la pregunta(0)

Su respuesta a la pregunta