我正在寻找有关如何识别 R 闪亮程序中内存泄漏的一般想法。我正在努力确定泄漏的确切位置,因此很难重新创建,而且我的代码已经超过 1000 行。我确信它与观察和观察事件有关,但我无法准确指出它。我实际上很喜欢 bborgeser 在这里提出的想法,使用选项,reactlog:https://github.com/rstudio/shiny/issues/1591 https://github.com/rstudio/shiny/issues/1591但是当我尝试这样做时, showReactLog() 将不会加载。我猜我的代码太大了。
所以我的主要问题是,识别内存泄漏的最佳方法是什么?我使用 pryr 包来跟踪每次提交后使用的内存。所以我可以看出内存正在增加。我发现了一些关于内存泄漏的其他文章,但它们更多的是要解决的具体问题,而不是一般性问题:https://github.com/rstudio/shiny/issues/931 https://github.com/rstudio/shiny/issues/931
由于有些人看到一些实际代码会更好地工作,因此我尽力更简洁地重新创建它。这将增加大约 0.3 mb/。也许这与在列表上使用列表有关?我已经摆弄我的东西几个星期了,但没有真正取得任何进展。
具体来说,在这段代码中,我知道内存泄漏肯定是在 Reactive/Observe 中。如果我阻止这些,内存就不会增加。但我确信您能够在不增加内存的情况下使用反应式和观察式。所以这让我回到了原来的问题,在这种情况下,我通过慢慢地屏蔽部分找到了它,但即使当我在更大的代码上尝试时,我也无法真正识别它来自哪个部分。那么人们如何找到漏洞呢?
#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)