使用 observeEvent 发生内存泄漏
Memory leak by using observeEvent
我使用以下代码获取累积内存。每次我在操作按钮 1 和 2 之间切换时,使用的内存都会增加。
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)
由于 this post 中的建议,我尝试不使用 observeEvent。这是服务器功能:
server <- function(input, output) {
# 1
output$plot <- renderPlot({
input$action_input_1
plot(rnorm(100))
print(cat(paste0("mem used 1: ", capture.output(print(mem_used())),"\n")))
})
# 2
output$plot <- renderPlot({
input$action_input_2
plot(rnorm(1000))
print(cat(paste0("mem used 2: ", capture.output(print(mem_used())),"\n")))
})
}
这里内存没有增加,只有第二个动作按钮(=最后一段代码?)起作用了。是否有防止内存泄漏并使两个按钮都正常工作的解决方案?
使用 reactiveVal 怎么样:
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))
我使用以下代码获取累积内存。每次我在操作按钮 1 和 2 之间切换时,使用的内存都会增加。
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)
由于 this post 中的建议,我尝试不使用 observeEvent。这是服务器功能:
server <- function(input, output) {
# 1
output$plot <- renderPlot({
input$action_input_1
plot(rnorm(100))
print(cat(paste0("mem used 1: ", capture.output(print(mem_used())),"\n")))
})
# 2
output$plot <- renderPlot({
input$action_input_2
plot(rnorm(1000))
print(cat(paste0("mem used 2: ", capture.output(print(mem_used())),"\n")))
})
}
这里内存没有增加,只有第二个动作按钮(=最后一段代码?)起作用了。是否有防止内存泄漏并使两个按钮都正常工作的解决方案?
使用 reactiveVal 怎么样:
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))