楼主: 黑白纯
4562 3

[问答] R语言内存耗尽,Error: memory exhausted (limit reached?) [推广有奖]

  • 0关注
  • 0粉丝

大专生

63%

还不是VIP/贵宾

-

威望
0
论坛币
20 个
通用积分
9.9145
学术水平
3 点
热心指数
3 点
信用等级
3 点
经验
525 点
帖子
30
精华
0
在线时间
48 小时
注册时间
2019-10-25
最后登录
2021-10-16

楼主
黑白纯 发表于 2020-3-1 03:41:57 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
最近跑一个循环比较多的程序,需要执行两千多万次的基因比对以及二项式计算,之前一直用for循环跑,但是速度真的很慢,于是百度查了一下多线程的使用问题。发现parallel和foreach包可以实现多线程的操作,加快运行速度。通过detectCore()函数得知我的电脑能同时运行12个线程。于是先进行了检测,发现在1万次甚至10万次的循环中。12线程的foreach循环速度均要比单线程的foreach循环速度还要慢(用法是没出现错误的,多线程%dopar%,单线程%do%)。虽然可能每次只是慢了几秒钟。于是我怀疑是不是我没有成功打开多线程?但是多次检查程序也没发现有什么问题,程序如下

c1<-makeCluster(12)
registerDoParallel(c1)
ptm<-proc.time()
b<-foreach(i=c(1:10000),.combine = 'rbind') %dopar% {
  reverse_num<-sum(GSE9348[which(GSE9348[,1]==stable_pair[i,1]),2:GSE9348_num_patients]<GSE9348[which(GSE9348[,1]==stable_pair[i,2]),2:GSE9348_num_patients])
  dbinom(reverse_num,GSE9348_num_patients-1,0.01)#每个患者中该稳定对逆转的概率为0.01,在GSE9348_num_patients个患者中,该基因对出现逆转的次数为reverse_num,概率存在binom_pvalue[i,1]中
}
stopCluster(c1)
proc.time()-ptm


由于还是相信多线程的运算能力,所以最后我还是用多线程跑的前1000w个基因对(一共2000w个)。结果原本测试过程中1w次循环需要6.6s,理论上1000w次循环在2个小时内绝对可以跑完了,但是结果却大大出乎意料,1000w次的循环竟然跑了14个小时才结束。
然后我就想,是不是内存占用的原因导致的时间延长了这么多呢?又各种搜索资料找R内存相关的知识,感觉算是搜了个一知半解。得知看已占内存的方法memory.size(F)和清理内存的方法gc(),按照我的理解,在我没有增加变量名的情况下,也就不会增加新的变量,就不会出现新的变量导致内存不够的问题,R语言发现多余的堆积内存会自动执行gc()方法,能够清理R语言执行过程中产生的临时变量(这是我的理解,举个例子就是假如循环中有cbind,R会不断开拓内存空间存储新的matrix,导致内存累计,但是gc()应该能清理这些内存的堆积,但是我在之后的尝试中觉得我理解可能有误了,gc()方法好像并没有这么强大。

然后为了证明多线程确实能比单线程运行速度快,我在百度查了很多parallel的使用方法,但是都没给出具体的时间证据来证明foreach方法的多线程速度快于单线程,而parapply方法却有证据表明速度是快于Lapply的,其中发现了一个程序如下
square <- function(x)
{
  #########
  #一段冗余代码增加执行时间
  y = 2*x
  if(y <300)
  {z = y}
  else
  {z = x}
  ##########   
  return(x^2)
}
num <- c(1:10000000)
cl <- makeCluster(12) # 初始化四核心集群
system.time({
  results <- parLapply(cl,num,square)#调用parLapply并行计算平方函数
  final <- do.call('c',results)#整合结果
  stopCluster(cl) # 关闭集群
})

system.time({
  results <- lapply(num,square)
  final <- do.call('c',results)#整合结果
})

这个程序没涉及到foreach方法,但是得到的结果显示多线程的速度的确会高于单线程,我用电脑跑完发现多线程用时10s左右,单线程12s左右(我跑了很多次,每次结果都不一样,这里给了个大致的值)。我考虑到可能是因为num的范围还是不够大导致两种线程速度差异不明显,于是我将num由1000w增加至5000w 。然后跑了将近两分钟的时候上边多线程的方法就开始报错
Error: memory exhausted (limit reached?)
这时候我用memory.size(F)看了下R的已用内存显示
> memory.size(F)
[1] 3433.63

我设置的内存上限是8020M
> memory.limit()
[1] 8082

这么一看明明没有满,但是确保错内存耗尽?我以为有系统堆积的无用内存导致的这个原因,于是gc()之后,发现memory.size(F)还是3433.63 。然后我的人生观崩塌了
说了这么多,查了这么多,总结一下我的问题就是
1.多线程的foreach循环为什么会比单线程的foreach循环慢?
2.为什么1w次循环仅需要6.6s,但是1000w次的循环却需要14个小时?
3.已用内存仅仅是3433M,内存上限有8082M,为什么会出现内存耗尽的报错?
4.循环的过程中没有产生新的变量名,原本在上述程序运行前,memory.size仅仅为200多M,运行中途报错导致结果变量final没有出现为什么内存会堆积到3433M?
5.gc()清理的到底是什么?
对于R我了解的虽然少,但是希望能多跟前辈们学习,希望有大神能帮我解答,万分感谢!
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:R语言 内存不足问题 运行报错 多线程并行计算

沙发
黑白纯 发表于 2020-3-1 03:55:37
其中第四个问题我发现原因了,results变量存储内存超过了3000M,但是其余的四个问题还需要大神帮忙解答,谢谢

藤椅
Sherry011 发表于 2024-10-18 13:43:29
你好,这个问题解决了吗?
我是数据比较少的时候能看到并行是快。但是数据比较多的时候,就发现并行一直是sleep的状态,好像是主程序在读数据,内存一直在增。而后端并行的程序都一致休眠。

板凳
kkwei 发表于 2024-10-28 08:59:07
用Python

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-3 02:58