【发布时间】:2016-08-10 17:51:28
【问题描述】:
全部,
我有一个只有 ~120MB 的 CSV 文件(称之为demo.csv)
以下代码导致堆从正常大小100MB 爆炸到1.7GB,尽管加载的基础数据仅为120MB
我可以在这里做得更好吗?
case class Foo(x:String, y: Array[String])
....
val src = Source.fromFile(file)
val lines = src.getLines()
val raw = lines.map(_.split(",")).toArray
src.close()
/**
* a map from accountId to their benchmark components
*/
val result = raw.groupBy(_.(0)).map {
case (x, y) => Foo(x,y)
}.toArray
我知道toArray 可能是这里的问题,但是我确实需要groupBy ...并且除非我将所有内容都放入内存中,否则我无法使用它。什么是替代品?
我了解堆在groupBy 和toArray 阶段可能会暂时膨胀。但是由于底层数据只有 120MB,我的堆怎么可能永久增加>1G? (换句话说,任何被保留的东西似乎都不是 GC-ed)
【问题讨论】:
-
你为什么不使用 List 或 Seq?此外,让您的结果可迭代以提高性能可能是值得的。
-
用列表替换数组似乎没有什么区别。我不能将其保留为迭代器,因为此方法的结果对象必须是 Seq[Foo] where Foo.y: Array[Array[String]] 的形式
-
你如何检查堆? Java 不会缩小其堆大小,它只会增长直到达到 Xmx VM 设置。 GC 只改变堆中的可用内存量,而不改变堆的大小。
-
我正在使用 Runtime.getRuntime
-
创建一个堆转储,安装MAT然后检查实际占用的内存量和占用它的内容。
标签: java scala csv io heap-memory