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

RStudio创建大型环境对象触发protect(): protection stack overflow报错咨询

RStudio创建大型哈希环境时触发protect()栈溢出错误

问题背景

我需要创建一个大型键值对查找表,尝试用如下代码实现:

# 实际使用场景下长度约为500万
key <- do.call(paste0, Map(stringi::stri_rand_strings, n=2e5, length = 16))
val <- sample.int(750, size = 2e5, replace = T)

make_dict <- function(keys, values){
  require(rlang)
  e <- new.env(size = length(keys))
  l <- list2(!!!setNames(values, keys))
  list2env(l, envir = e, hash = T) # 问题是否出在这里?
}

d <- make_dict(key, val)

问题现象

运行make_dict函数时会抛出Error: protect(): protection stack overflow错误。该问题仅在RStudio中输入向量长度大于49991时出现,和同类fread报错的触发场景高度相似。
但我运行取值函数提取部分值验证时,发现make_dict实际运行正常,结果无异常:

`%||%` <- function(x,y) if(is.null(x)) y else x
grab <- function(...){
  vector("integer", length(..2)) |>
    (\(.){. = Vectorize(\(e, x) e[[x]] %||% NA_integer_, list("x"), T, F)(..1, ..2); .})()
}
out <- vector("integer", length(key))
out <- grab(d, sample(key)) # 打乱键的顺序测试

anyNA(out) | !lobstr::obj_size(out) == lobstr::obj_size(val)
[1] FALSE

相同代码在RGui中运行不会抛出该错误。

异常特征

  • 当环境大小超过5万时,d环境对象不会显示在RStudio的环境面板中
  • R控制台快速返回>提示符(说明函数已运行完成),但报错前控制台处于无响应状态
  • 无论手动设置options(expressions = 5e5),还是保留默认值5000,均会触发报错
  • 报错的触发时间与输入向量的大小正相关
  • tryCatch(make_dict(key, val), error = function(e) e)无法捕获该错误
  • 从包中运行该代码也会触发报错

咨询问题

该报错的成因是什么?如何排查这类错误?
按照通用调试教程建议设置options(error = traceback)未返回任何结果。在make_dict函数的list2env后插入browser(),浏览器打开很久后才会抛出错误。traceback()结果指向函数.rs.describeObject,该函数用于生成环境面板的对象摘要,相关代码如下:

traceback()

# .rs.describeObject
(function (env, objName, computeSize = TRUE) 
   {
       obj <- get(objName, env)
       hasNullPtr <- .Call("rs_hasExternalPointer", obj, TRUE, PACKAGE = "(embedding)")
       if (hasNullPtr) {
           val <- "<Object with null pointer>"
           desc <- "An R object containing a null external pointer"
           size <- 0
           len <- 0
       }
       else {
           val <- "(unknown)"
           desc <- ""
           size <- if (computeSize) 
               object.size(obj)
           else 0
           len <- length(obj)
       }
       class <- .rs.getSingleClass(obj)
       contents <- list()
       contents_deferred <- FALSE
       if (is.language(obj) || is.symbol(obj)) {
           val <- deparse(obj)
       }
       else if (!hasNullPtr) {
           if (size > 524288) {
               len_desc <- if (len > 1) 
                   paste(len, " elements, ", sep = "")
               else ""
               if (is.data.frame(obj)) {
                   val <- "NO_VALUE"
                   desc <- .rs.valueDescription(obj)
               }
               else {
                   val <- paste("Large ", class, " (", len_desc, 
                     format(size, units = "auto", standard = "SI"), 
                     ")", sep = "")
               }
               contents_deferred <- TRUE
           }
           else {
               val <- .rs.valueAsString(obj)
               desc <- .rs.valueDescription(obj)
               if (class == "data.table" || class == "ore.frame" || 
                   class == "cast_df" || class == "xts" || class == 
                   "DataFrame" || is.list(obj) || is.data.frame(obj) || 
                   isS4(obj)) {
                   if (computeSize) {
                     contents <- .rs.valueContents(obj)
                   }
                   else {
                     val <- "NO_VALUE"
                     contents_deferred <- TRUE
                   }
               }
           }
       }
       list(name = .rs.scalar(objName), type = .rs.scalar(class), 
           clazz = c(class(obj), typeof(obj)), is_data = .rs.scalar(is.data.frame(obj)), 
           value = .rs.scalar(val), description = .rs.scalar(desc), 
           size = .rs.scalar(size), length = .rs.scalar(len), contents = contents, 
           contents_deferred = .rs.scalar(contents_deferred))
   })(<environment>, "d", TRUE)

内容的提问来源于stack exchange,提问作者Donald Seinen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:54:03