解决内存泄漏-Shiny R

时间:2018-10-26 16:34:27

标签: r memory-leaks shiny

我的闪亮程序存在内存泄漏,并且正在努力解决。我将显示的代码泄漏很小,但是对于我的实际代码,损失却更大,几天之内就可以累积千兆字节。我一直在努力简化它,但是仍然显示问题,这是我能想到的最好的方法。我使用了三个软件包,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 - Suggestions on how to find?从那以后,我仍在研究模块看看是否有帮助。

谢谢您的帮助。

0 个答案:

没有答案