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

使用terra包时如何解决for循环中的bad:alloc内存错误?

栅格提取时的内存分配错误(bad:alloc)问题

我使用terra包编写代码,从一组多边形中提取栅格值。该栅格被划分为约20个分块(tile),通过for循环逐个处理。但程序总会触发bad:alloc错误(推测是内存不足导致),处理完约6个分块(跳过约3个与多边形无重叠的分块)后就会终止。

已尝试的解决方法

  • 每次迭代后清理R生成的临时文件,同时设置terra的临时目录参数:
    terraOptions(tempdir=tempdir, steps = 10)
    unlink(file.path(tempdir, "*"), recursive = TRUE) # 清理临时文件目录
    
  • 将每个分块的结果数据表(含数千行)保存为RDS文件,避免内存堆积:
    saveRDS(result, file=paste("./Cropped/HansenCover2000/Extract/", tileNumber, ".rds", sep=""))
    
    其中tileNumber随每次迭代自增1。
  • 处理完当前分块后,从R环境中移除当前栅格对象和结果表,并手动触发垃圾回收:
    rm(result, tile) 
    gc()
    
  • 每个分块已提前根据多边形完成掩膜和裁剪,裁剪后的栅格大小在4MB到229MB之间。程序终止时并非处理最大的分块,且此前已成功处理过190MB的分块。

单独运行单个分块的代码可以正常执行,但放入for循环后就会出现错误。原本计划在terra::extract中添加exact=TRUE参数,但该操作会让内存问题更严重。

代码示例

cropCover2000 <- list.files("./Cropped/HansenCover2000", pattern="\\.tif$") # 获取裁剪后栅格的路径
dirCreate("./Cropped/HansenCover2000/Extract")
tileNumber <-1

for(coverTiles in cropCover2000) # 遍历所有分块
{
  unlink(file.path(tempdir, "*"), recursive = TRUE) # 清理临时文件目录
  tile <- rast(paste("./Cropped/HansenCover2000", coverTiles, sep="/")) # 读取分块栅格
  
  result <- terra::extract(tile, species, na.rm=TRUE)
  colnames(result) <- c("ID", "Cover2000")
  result <- group_by(result, ID, Cover2000) %>%
    reframe(count=length(Cover2000), .groups="keep")
  saveRDS(result, file=paste("./Cropped/HansenCover2000/Extract/", tileNumber, ".rds", sep=""))
  tileNumber <- tileNumber +1
  rm(result, tile)
  gc()
}

循环完成后(目前尚未成功执行完毕),我会对生成的RDS文件进行后续处理。

内容的提问来源于stack exchange,提问作者Jacob Cummings

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:55:56