You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shiny Server的rgl应用中避免内存不足及优化咨询

问题描述

我开发了一个基于rgl的Shiny应用,本地运行完全正常,但部署到shinyapps.io后频繁崩溃。日志显示Container event from container-8564782: oom (out of memory),推测是平台默认的1GB内存不足以支撑应用运行。

应用核心逻辑:在rglwidget()中渲染6个结构复杂的triangle3d()对象,点击按钮会生成这些对象的平移新版本并绘制到新rgl场景中。我已尝试设置lit=FALSE节省内存,但崩溃问题仍存在(非每次触发);同时怀疑旧rgl对象未被正确清理,试过rglwidget(reuse=NA)和webGLoptions = list(preserveDrawingBuffer = FALSE),但部署测试效率太低。

现有两个疑问:

  1. 能否在本地模拟1GB内存环境测试应用?
  2. 使用rgl和Shiny开发时,还有哪些有效的内存优化手段?

核心代码如下:

observe({ 
    input$randomise 
    #### Create a random position of each objects using translate3d, plot them using triangle3d.
    amessage = random_obj( objects= objects, position_tot =position_tot, messagesday=messagesday, colorpalette=palette("Okabe-Ito"))
    
    output$rglPlot <- renderRglwidget({
      
      createboden()
      
      view3d (theta = 0, phi = -88, zoom = 0.8, fov = 60)
      outputwidget = rglwidget(reuse=NA, webGLoptions = list(preserveDrawingBuffer = FALSE))
      
      
      outputwidget

    })
})
解决方案

1. 本地模拟1GB内存环境测试

  • Linux/macOS:在终端执行ulimit -v 1048576(1GB=1024*1024KB)限制进程内存,随后在同一终端启动R并运行Shiny应用,触发内存不足时会直接崩溃,还原shinyapps.io的OOM场景。
  • Windows:可以用Windows Sysinternals的VMMap监控内存占用,或通过Docker创建内存限制为1GB的容器,在容器内运行R和Shiny应用,模拟受限环境。

2. rgl/Shiny内存优化手段

  • 主动清理旧场景:每次生成新内容前,调用rgl::clear3d(type = "all")彻底清空当前rgl设备的所有对象、灯光和视图设置,避免旧对象残留占用内存,比依赖reuse=NA自动清理更可靠。
  • 简化3D模型:
    • 检查triangle3d的顶点数量,合并共面三角形或用简化算法降低模型复杂度,减少绘制所需的内存。
    • 若模型为外部导入,先在建模软件中简化后再导入R,避免在rgl中处理高复杂度模型。
  • 复用rgl设备:不要每次点击都重建rglwidget,将设备ID存入reactiveVal,后续更新时在同一设备上修改内容,而非重建整个组件:
    # 初始化rgl设备
    rgl_dev <- reactiveVal(rgl::open3d())
    
    observeEvent(input$randomise, {
      # 清空当前设备内容
      rgl::clear3d(type = "all", dev = rgl_dev())
      # 绘制新场景
      createboden(dev = rgl_dev())
      view3d(theta = 0, phi = -88, zoom = 0.8, fov = 60, dev = rgl_dev())
      # 更新输出
      output$rglPlot <- renderRglwidget({
        rglwidget(dev = rgl_dev(), reuse = TRUE)
      })
    })
    
  • 禁用冗余WebGL特性:除lit=FALSE外,可设置texture=FALSE(无纹理需求时)、smooth=FALSE(无需平滑着色),减少GPU和CPU内存占用。
  • 缓存重复计算:若random_obj函数存在重复计算逻辑,缓存基础数据,避免每次点击都重新生成相同内容。
  • 监控内存泄漏:本地用memory.size()(Windows)或gc()结合utils::memory.profile()跟踪内存变化,定位未被正确回收的对象。

内容的提问来源于stack exchange,提问作者Julien Colomb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:35:18