我可以确认在Windows 7上存在内存问题(通过MacOSX上的VMware Fusion运行)。虽然内存使用似乎相当逐渐(未经证实但表明存在内存泄漏),但它似乎也存在于MacOSX上。由于操作系统在看到高使用率时会压缩内存,因此在MacOSX上稍微有些棘手。
鉴于以上情况,我的建议是从美国人口普查局下载表格时将下载集拆分为较小的组。为什么?好吧,看看你正在下载数据以存储在.CSV文件中的代码。因此,短期内的解决方法是分割你要下载的表格列表。您的程序应该能够在一组运行中成功完成。
其中一种选择是创建一个包装器RScript并使其在N个运行中运行,每个运行调用一个单独的R会话。即Rscript按顺序调用N个RSessions,每个会话下载N个文件。
根据您的代码和观察到的内存使用情况,我感觉您正在下载大量表格,因此跨R会话进行拆分可能是最佳选择。
注意:以下内容应在Windows 7上的cgiwin下运行。
调用脚本示例:如果主表01到27不存在,则跳过...
!
for CensusTableCode in $(seq -w 1 27)
do
R --no-save -q --slave < ./PullCensus.R --args B"$CensusTableCode"001 2014 5
done
PullCensus.R
if (!require(acs)) install.packages("acs")
if (!require(pryr)) install.packages("pryr")
api.key.install(key = "** Secret**")
setwd("~/dev/stackoverflow/37264919")
args <- commandArgs(trailingOnly = TRUE)
if ( length(args) != 0 ) {
tableCodes <- args[1]
defEndYear = args[2]
defSpan = args[3]
} else {
tableCodes <- c("B02001")
defEndYear = 2014
defSpan = 5
}
for (i in 1:length(tableCodes))
{
tryCatch(
table <- acs.fetch(table.number = tableCodes[i],
endyear = defEndYear,
span = defSpan,
geography = geo.make(state = "NY",
county = "*",
tract = "*"),
col.names = "pretty"),
error = function(e) { print("Table skipped")} )
if (exists("table", mode = "S4"))
{
print(paste("Table", i, "fetched"))
if (!is.na(table))
{
write.csv(estimate(table), paste(defEndYear,"_",tableCodes[i], ".csv", sep = ""))
}
print(mem_used())
print(mem_change(rm(table)))
gc(reset = TRUE)
print(mem_used())
}
}
我希望通过示例向您展示一种方法。这是一种方法。;-)
T.
下一步:
我将查看软件包源代码,以查看实际上出了什么问题。或者,您自己可能能够缩小范围,并针对软件包提交错误报告。
背景 / 工作示例:
我的感觉是提供一个工作代码示例来解释上述解决方法可能会有所帮助。为什么?这样做的目的是为了提供一个人们可以用来测试和考虑发生了什么事情的示例。为什么?好吧,这使得更容易理解您的问题和意图。
本质上,(据我了解)您正在从美国人口普查网站批量下载美国人口普查数据。表格代码用于指定要下载的数据。好的,所以我刚刚创建了一组表格代码,并测试了内存使用情况,以查看是否会像您解释的那样消耗内存。
library(acs)
library(pryr)
library(tigris)
library(stringr)
library(maptools)
api.key.install(key = "<INSERT KEY HERE>")
setwd("~/dev/stackoverflow/37264919")
tablecodes <- c("B19001", "B19001A", "B19001B", "B19001C", "B19001D",
"B19001E", "B19001F", "B19001G", "B19001H", "B19001I" )
for (i in 1:length(tablecodes))
{
print(tablecodes[i])
tryCatch(
table <- acs.fetch(table.number = tablecodes[i],
endyear = 2014,
span = 5,
geography = geo.make(state = "NY",
county = "*",
tract = "*"),
col.names = "pretty"),
error = function(e) { print("Table skipped")} )
if (exists("table", mode="S4"))
{
print(paste("Table", i, "fetched"))
if (!is.na(table))
{
write.csv(estimate(table), paste("T",tablecodes[i], ".csv", sep = ""))
}
print(mem_used())
print(mem_change(rm(table)))
gc()
print(mem_used())
}
}
运行时输出
> library(acs)
> library(pryr)
> library(tigris)
> library(stringr)
> library(maptools)
>
>
> api.key.install(key = "...secret...")
>
...
> setwd("~/dev/stackoverflow/37264919")
>
>
>
>
>
>
>
>
> tablecodes <- c("B19001", "B19001A", "B19001B", "B19001C", "B19001D",
+ "B19001E", "B19001F", "B19001G", "B19001H", "B19001I" )
>
>
> for (i in 1:length(tablecodes))
+ {
+ print(tablecodes[i])
+ tryCatch(
+ table <- acs.fetch(table.number = tablecodes[i],
+ endyear = 2014,
+ span = 5,
+ geography = geo.make(state = "NY",
+ county = "*",
+ tract = "*"),
+ col.names = "pretty"),
+ error = function(e) { print("Table skipped")} )
+
+
+ if (exists("table", mode="S4"))
+ {
+ print(paste("Table", i, "fetched"))
+ if (!is.na(table))
+ {
+ write.csv(estimate(table), paste("T",tablecodes[i], ".csv", sep = ""))
+ }
+ print(mem_used())
+ print(mem_change(rm(table)))
+ gc()
+ print(mem_used())
+ }
+ }
[1] "B19001"
[1] "Table 1 fetched"
95.4 MB
-1.88 MB
93.6 MB
[1] "B19001A"
[1] "Table 2 fetched"
95.4 MB
-1.88 MB
93.6 MB
[1] "B19001B"
[1] "Table 3 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001C"
[1] "Table 4 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001D"
[1] "Table 5 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001E"
[1] "Table 6 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001F"
[1] "Table 7 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001G"
[1] "Table 8 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001H"
[1] "Table 9 fetched"
95.5 MB
-1.88 MB
93.6 MB
[1] "B19001I"
[1] "Table 10 fetched"
95.5 MB
-1.88 MB
93.6 MB
输出文件
>ll
total 8520
drwxr-xr-x@ 13 hidden staff 442B Oct 17 20:41 .
drwxr-xr-x@ 40 hidden staff 1.3K Oct 17 23:17 ..
-rw-r--r--@ 1 hidden staff 4.4K Oct 17 23:43 37264919.R
-rw-r--r--@ 1 hidden staff 492K Oct 17 23:50 TB19001.csv
-rw-r--r--@ 1 hidden staff 472K Oct 17 23:51 TB19001A.csv
-rw-r--r--@ 1 hidden staff 414K Oct 17 23:51 TB19001B.csv
-rw-r--r--@ 1 hidden staff 387K Oct 17 23:51 TB19001C.csv
-rw-r--r--@ 1 hidden staff 403K Oct 17 23:51 TB19001D.csv
-rw-r--r--@ 1 hidden staff 386K Oct 17 23:51 TB19001E.csv
-rw-r--r--@ 1 hidden staff 402K Oct 17 23:51 TB19001F.csv
-rw-r--r--@ 1 hidden staff 393K Oct 17 23:52 TB19001G.csv
-rw-r--r--@ 1 hidden staff 465K Oct 17 23:44 TB19001H.csv
-rw-r--r--@ 1 hidden staff 417K Oct 17 23:44 TB19001I.csv
mem_used
中显示,但会在系统监视器中显示。据我所知,acs
没有任何 C/C++ 代码,但它使用了XML
包。可能是acs
没有释放由XML
分配的内存,或者XML
包存在内存泄漏问题(在 Windows 下据说存在此问题:http://www.omegahat.net/RSXML/)。 - Jan van der Laanhttr
直接调用 API。如果您直接构造 API 调用,则不应该有任何内存泄漏问题。我在acs
包中也遇到了同样的问题。 - trohgc(T)
替换gc()
吗? - Zeinab Ghaffarnasab