首页 > 解决方案 > 解决内存泄漏 - Shiny R

问题描述

我的闪亮程序出现内存泄漏,我正在努力解决这个问题。对于我将展示的代码,我的泄漏非常小,但对于我的实际代码,它的损失要大得多,在几天内累积了千兆字节。我一直在努力简化这个,但仍然显示问题,这是我能想到的最好的。我使用了三个包,shiny,shinyjs 来重置页面,pryr 来显示内存丢失。

本质上,只需输入数字,然后单击提交按钮即可重置/打印内存。如果前两个数字的平均值高于 5,则会创建第二个框。如果任一方框的平均值低于 5,但不是 0,则您可以提交并重置。

    #Library Load##########################################################################################
lapply(c("shiny","shinyjs","pryr"),require,character.only = T)
#ui, shiny body#########################################################################################
ui<-fluidPage(
  useShinyjs(),
  #Div to reset the whole page upon submission
  div(id = paste0("BOX_"),
      h3("Add random numbers. If average is above 5, an additional box will be added. If below 5, click reset to reset the page and update memory"),
      #lapply - Add 2 boxes with double numeric inputs and average
      column(width = 5, align = "center",
      lapply(seq(1,3,2),function(y){
          div(id = paste0("Box_ID_","_",y),
                         numericInput(paste0("Number_",y), label = paste0("Number - ",y), value = 0, min = 0, max = 60, step = .1),
                         numericInput(paste0("Number_",y+1), label = paste0("Number - ",y+1), value = 0, min = 0, max = 60, step = .1),
                         h3(textOutput(paste0("Avg_",y))))
      })),
      column(width = 1),
      #Submit and memory used#########
          actionButton(paste0("Complete_"),"Reset"),
          br(),
      h4("Memory output - Updates on submit"),
      textOutput(paste0("Memory"))
))
#######Server################
server <- function(input, output, session) {
  #Reactive Average#########
  Avg<-reactive({
    lapply(seq(1,3,2),function(y){
      req(input[[paste0("Number_",y)]],input[[paste0("Number_",y+1)]])
      if(input[[paste0("Number_",y)]] == 0 | input[[paste0("Number_",y+1)]] == 0) {0} else {
        (input[[paste0("Number_",y)]]+input[[paste0("Number_",y+1)]])/2}
    })
  })
  #Average Output##########
  lapply(seq(1,3,2),function(y){
    output[[paste0('Avg_',y)]] <- renderText({
      req(input[[paste0("Number_",y)]],input[[paste0("Number_",y+1)]])
      if(input[[paste0("Number_",y)]] == 0 | input[[paste0("Number_",y+1)]] == 0) {
        "Enter both numbers"} else{
          paste0("Average = ",round(Avg()[[(y/2)+.5]],1))}
    })
  })
  # Enable/Disable Submit button if average is not 0, and below 5
    observe({
      lapply(seq(1,3,2),function(y){
      req(input[[paste0("Number_",y)]], input[[paste0("Number_",y+1)]])
      if(Avg()[[1]] > 0 & Avg()[[1]] <= 5 | Avg()[[2]] > 0 & Avg()[[2]] <= 5 ) {
        shinyjs::enable(paste0("Complete_"))} else{shinyjs::disable(paste0("Complete_"))}
    })
  })
  #Show next average box if average is not below 5
    observe({
      lapply(seq(1,3,2),function(y){
      req(input[[paste0("Number_",y)]],input[[paste0("Number_",y+1)]])
      if(y == 1 & Avg()[[(y/2)+.5]] <= 5) {
        shinyjs::show(paste0("Box_ID_","_",1))
        shinyjs::hide(paste0("Box_ID_","_",3))
      } else if(y == 1 & Avg()[[(y/2)+.5]] > 5) {
        shinyjs::show(paste0("Box_ID_","_",1))
        shinyjs::show(paste0("Box_ID_","_",3))
      } else if(Avg()[[(y/2)+.5]] > 5) {
        shinyjs::show(paste0("Box_ID_","_",y+2))
      } else {shinyjs::hide(paste0("Box_ID_","_",y+2))}
    })
  })
  #Submit Button - Reset boxes, print memory######
  observeEvent(input[[paste0("Complete_")]],{
    #Reset the page
    reset(paste0("BOX_"))
    #Garabage collect
  })
  #Memory used############
  observeEvent(input[[paste0("Complete_")]],{
    output[[paste0("Memory")]]<-renderText({
      paste0(round(mem_used()/1000000,3)," mb")
    })
  })
}
# Run App
shinyApp(ui, server)

我最好的猜测是泄漏来自观察/观察事件。我已经尝试过这里描述的反应日志:https ://github.com/rstudio/shiny/issues/1591但我并没有完全弄清楚问题出在哪里. 我也对此进行了研究,但我没有在观察中使用任何输出:https ://github.com/rstudio/shiny/issues/1551我之前写过,询问有关如何查找内存泄漏的想法:R Shiny Memory Leak - 关于如何找到的建议?从那以后,我仍在研究模块,看看是否有帮助。

感谢您的任何帮助。

标签: rmemory-leaksshiny

解决方案


推荐阅读