我的代码如下所示(它与原始版本相比有点简化版本,但它仍然反映了问题)。
require(VGAM)
Median.sum = vector(mode="numeric", length=75)
AA.sum = vector(mode="numeric", length=75)
BB.sum = vector(mode="numeric", length=75)
Median = array(0, dim=c(75 ,3))
AA = array(0, dim=c(75 ,3))
BB = array(0, dim=c(75 ,3))
y.sum = vector(mode="numeric", length=100000)
y = array(0, dim=c(100000,3))
b.size = vector(mode="numeric", length=3)
c.size = vector(mode="numeric", length=3)
for (h in 1:40)
{
for (j in 1:75)
{
for (i in 1:100000)
{
y.sum[i] = 0
for (f in 1:3)
{
b.size[f] = rbinom(1, 30, 0.9)
c.size[f] = 30 - rbinom(1, 30, 0.9) + 1
y[i, f] = sum( rlnorm(b.size[f], 8.5, 1.9) ) +
sum( rgpd(c.size[f], 120000, 1870000, 0.158) )
y.sum[i] = y.sum[i] + y[i, f]
}
}
Median.sum[j] = median(y.sum)
AA.sum[j] = mean(y.sum)
BB.sum[j] = quantile(y.sum, probs=0.85)
for (f in 1:3)
{
Median[j,f] = median(y[,f])
AA[j,f] = mean(y[,f])
BB[j,f] = quantile(y[,f], probs=0.85)
}
}
#gc()
}
它在执行中断(h = 7,j = 1,i = 93065)并出现错误:
Error: cannot allocate vector of size 526.2 Mb
收到此消息后,我已阅读this,this& this,但还不够。问题是,垃圾收集器(gc())和清除工作区中的所有对象都没有帮助。我的意思是我试图将我的代码放入:垃圾收集器和操作删除所有变量并在循环内再次声明它们(看看#gc()所在的位置 - 但后者是未包含在我发布的代码中。
对我来说这似乎很奇怪,因为所有过程在循环的每个步骤中都使用相同的对象(=>并且应该在循环的每个步骤中消耗相同的内存量)。为什么内存消耗会随着时间的推移而增加?
为了使问题变得更糟,如果我想在R的同一个会话中工作甚至执行:
rm(list=ls())
gc()
我仍然会收到相同的错误消息,即使我想声明一些次要内容,例如:
abc = array(0, dim=c(10,3))
只关闭R并开始新会话有帮助。为什么?也许有一些方法可以重新编码我的循环?
R:2.15.1(32位),操作系统:Windows XP(32位)
我在这里很新,所以每个小费都赞赏!提前谢谢。
编辑(来自Arun)。我发现这个行为更容易通过一个简单的例子重现。启动新R会话并复制并粘贴此代码,并在系统监视器中观看内存增长。
mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
for (j in 1:1e3) {
for (k in 1:1e4) {
mm[k] <- k # already pre-allocated
}
}
}
答案 0 :(得分:4)
在gc()
循环中添加对for (i in 1:100000)
的调用。
在Arun代码的紧密循环中添加对gc()
的调用会消除其内存增长。
这显示了内存增长:
mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
for (j in 1:1e3) {
for (k in 1:1e4) {
mm[k] <- k # already pre-allocated
}
}
}
这不是:
mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
for (j in 1:1e3) {
for (k in 1:1e4) {
mm[k] <- k # already pre-allocated
gc()
}
}
}
这里有自动垃圾收集的问题。正如gcinfo(TRUE)
所示,在第一种情况下调用收集器。但是记忆力的增长很快。
答案 1 :(得分:2)
这似乎有效(将最内层的循环放入函数中)。我没有运行它直到结束,因为它会减慢,但我没有注意到代码中的内存膨胀。
require(VGAM)
Median.sum = vector(mode="numeric", length=75)
AA.sum = vector(mode="numeric", length=75)
BB.sum = vector(mode="numeric", length=75)
Median = array(0, dim=c(75 ,3))
AA = array(0, dim=c(75 ,3))
BB = array(0, dim=c(75 ,3))
inner.fun <- function() {
y.sum = vector(mode="numeric", length=100000)
y = array(0, dim=c(100000,3))
b.size = vector(mode="numeric", length=3)
c.size = vector(mode="numeric", length=3)
for (i in 1:100000)
{
y.sum[i] = 0
for (f in 1:3)
{
b.size[f] = rbinom(1, 30, 0.9)
c.size[f] = 30 - rbinom(1, 30, 0.9) + 1
y[i, f] = sum( rlnorm(b.size[f], 8.5, 1.9) ) +
sum( rgpd(c.size[f], 120000, 1870000, 0.158) )
y.sum[i] = y.sum[i] + y[i, f]
}
}
list(y.sum, y)
}
for (h in 1:40)
{
cat("\nh =", h,"; j = ")
for (j in 1:75)
{
cat(j," ")
result = inner.fun()
y.sum = result[[1]]
y = result[[2]]
Median.sum[j] = median(y.sum)
AA.sum[j] = mean(y.sum)
BB.sum[j] = quantile(y.sum, probs=0.85)
for (f in 1:3)
{
Median[j,f] = median(y[,f])
AA[j,f] = mean(y[,f])
BB[j,f] = quantile(y[,f], probs=0.85)
}
}
}