通过使用watchEvent发生内存泄漏

时间:2019-12-11 14:17:40

标签: r memory memory-leaks shiny observers

我使用以下代码累积内存。每次在操作按钮1和2之间切换时,使用的内存就会增加。

var ChartBlockShopFirstMelt = new Morris.Donut({
        element: 'MychartViewArea',
        parseTime: false,
        dataLabelsPosition: 'outside',
        resize: true,
        //donutType: 'pie',
        dataLabels: true,
        hidehover: 'auto',
        //colors: [
        //    '#882222'
        //    ],

            data: [
              @foreach(var item in ListAreaAndSheare )
                {
                    @:{ label: "@item.Lable", value: "@Math.Round(item.VALUE,2)" },
                }
    ],

    });

    ChartBlockShopFirstMelt.options.data.forEach(function (label, i) {
        var lgn = $('<span style=margin-left:10px;background-color:' + ChartBlockShopFirstMelt.options.colors[i] + '>    </span><br>').text(label['label']).prepend();
        $("#legendFirstMelt").append(lgn);
    });

由于this帖子中的建议,我尝试不使用observeEvent。这是服务器功能:

library(ggplot2)
library(shiny)
library(lobstr)

ui <- navbarPage("Test",fluidPage(fluidRow(
                     column(width = 1, actionButton("action_input_1", label = "1")), 
                     column(width = 1, actionButton("action_input_2", label = "2")),
                     column(width = 10, plotOutput("plot", width = 1400, height = 800)))))

server <- function(input, output) {
  # 1
  observeEvent(input$action_input_1, {
    output$plot <- renderPlot({
      plot(rnorm(100))
    })
    print(cat(paste0("mem used 1: ", capture.output(print(mem_used())),"\n")))
  })

  # 2
  observeEvent(input$action_input_2, {
    output$plot <- renderPlot({
      plot(rnorm(1000))
    })
    print(cat(paste0("mem used 2: ", capture.output(print(mem_used())),"\n")))
  })
}
shinyApp(ui, server)

这里的内存没有增加,但是只有第二个动作按钮(=最后一个代码块?)在起作用。是否有解决方案来防止内存泄漏并使两个按钮正常工作?

1 个答案:

答案 0 :(得分:0)

如何使用reactVal:

reactiveData <- reactiveVal(NULL)
observeEvent(input$action_input_1, reactiveData(rnorm(100)))
observeEvent(input$action_input_2, reactiveData(rnorm(1000)))
output$plot <- renderPlot(plot(reactiveData()))

反应值的语法略有不同:

reactiveData <- reactiveValues(rnorm = NULL, bool_val = NULL) 

observeEvent(input$action_input_1,  {# reactiveData(rnorm(100), bool_val <- TRUE)) 
   reactiveData$rnorm <- rnorm(100)
   reactiveData$bool_val <- TRUE
})

observeEvent(input$action_input_2, { #reactiveData(rnorm(1000), bool_val <- FALSE)) 
  reactiveData$rnorm <- rnorm(1000)
  reactiveData$bool_val <-  FALSE
})

output$plot <- renderPlot(plot(reactiveData$rnorm))

尽管变量一致变化,所以从技术上讲,您仍然可以使用reactiveVal

reactiveData <- reactiveVal(list(rnorm = NULL, bool_val = NULL)) 

observeEvent(input$action_input_1, reactiveData(list(rnorm = 100, bool_val = TRUE)))

observeEvent(input$action_input_2, reactiveData(list(rnorm = 1000, bool_val = FALSE)))

output$plot <- renderPlot(plot(reactiveData()$rnorm))