4

以下に示すような二重ループがあります 。問題は、R (2.15.2) がますます多くのメモリを使用していて、その理由がわかりません。

私がそこでやっているために、これが内側のサイクル内で発生しrbind()なければならないことは理解していますが、外側のループの新しいサイクルが開始され、実際にオブジェクト ( 'xmlCatcher' ) が再利用されるときに R がメモリを取得し続ける理由がわかりません。

# !!!BEWARE this example creates a lot of files (n=1000)!!!!

require(XML)

chunk <- function(x, chunksize){
        # source: http://stackoverflow.com/a/3321659/1144966
        x2 <- seq_along(x)
        split(x, ceiling(x2/chunksize))
    }

chunky <- chunk(paste("test",1:1000,".xml",sep=""),100)

for(i in 1:1000){
writeLines(c(paste('<?xml version="1.0"?>\n <note>\n    <to>Tove</to>\n    <nr>',i,'</nr>\n    <from>Jani</from>\n    <heading>Reminder</heading>\n    ',sep=""), paste(rep('<body>Do not forget me this weekend!</body>\n',sample(1:10, 1)),sep="" ) , ' </note>')
,paste("test",i,".xml",sep=""))
}

for(k in 1:length(chunky)){
gc()
print(chunky[[k]])
xmlCatcher <- NULL

for(i in 1:length(chunky[[k]])){
    filename    <- chunky[[k]][i]
    xml         <- xmlTreeParse(filename)
    xml         <- xmlRoot(xml)
    result      <- sapply(getNodeSet(xml,"//body"), xmlValue)
    id          <- sapply(getNodeSet(xml,"//nr"), xmlValue)
    dummy       <- cbind(id,result)
    xmlCatcher  <- rbind(xmlCatcher,dummy)
    }
save(xmlCatcher,file=paste("xmlCatcher",k,".RData"))
}

この動作が発生する理由を誰かが知っていますか? すべてのオブジェクト (「xmlCatcher」など) はサイクルごとに再利用されることに注意してください。使用される RAM は、最初の「チャンク」サイクルの後もほぼ同じままであるはずです。

  • ガベージ コレクションは何も変更しません。
  • rbind を使用しなくても、何も変わりません。
  • より少ないxml関数を使用すると、実際にはメモリの取得が少なくなります-しかし、なぜですか?

これはバグですか、それとも何か見逃していますか?

4

3 に答える 3

7

メモリの再利用に関するあなたの理解は素晴らしいです。

新しい DummyCatcher を作成すると、古い DummyCatcher は参照されなくなり、ガベージ コレクションの候補になります。

メモリを再利用しているのではなく、新しいオブジェクトを作成して古いオブジェクトを破棄しています。

ガベージ コレクションによってメモリが解放されます。

また、Rprofmem を調べてメモリ使用量をプロファイルすることをお勧めします。

于 2012-12-21T12:00:13.890 に答える
4

この話の第2章rbindは、食いしん坊であることの常套手段としての話です。

rbindループ内での使用を避けることができます。

my.list <- vector('list', chunk[k])
for(i in 1:chunk[k]) {
   dummy <- dummy + 1
   my.list[[i]] <- data.frame(dummy)
}
DummyCatcher  <- do.call('rbind', my.list)
于 2012-12-21T10:28:36.713 に答える
2

そのXMLパッケージはばかげています!

この質問に対する答えは、ここMilan Bouchet-ValatuseInternalNodes=TRUEから来ましたxmlTreeParse。これにより、RAM の取得が停止しましたが、メモリの解放を手動で処理する可能性もあります。詳細については、こちらを参照してください。

于 2012-12-21T19:30:27.727 に答える