使用此代码为什么堆快速充满?

时间:2017-05-01 12:01:42

标签: scala memory-management memory-leaks jvm large-files

内存在5分钟内变满(30GB大小)。使用此代码,我只想将文本文件(3gb)条目读入地图,但是当我运行此代码时,10gb eden空间在3秒内变满,5分钟后,旧堆空间也变满了。可能是什么原因?这是代码:

object PairWordsReader extends App {

  val wordsAndCounts: Map[WordTuple, Int] =
    io.Source.fromFile("/home/katilsperm/pairWords.txt").getLines.map {
      string =>
        val Array(w1,w2,freq) = string.split(",")
        WordTuple(w1,w2) -> freq.toInt
    }.toMap
}

自定义元组类:

case class WordTuple(x: String, y: String) {
  override def equals(that: scala.Any): Boolean = that match {
    case that: WordTuple => ( that canEqual this ) && (
      (this.x == that.x && this.y == that.y) ||
        (this.x == that.y && this.y == that.x)
      )
    case _ => false
  }
  override def canEqual( that:Any ): Boolean = that.isInstanceOf[WordTuple]
  override def hashCode: Int = x.hashCode + y.hashCode
  override def toString: String = x + "," + y
}

在这里,visualvm截图可以更清楚地解释问题: Overview

System Monitor

Garbage Collector

Memory Usage

记忆力正在疯狂。为什么不用gc清理临时字符数组和String对象,只有HashMap条目占用内存。我做错了什么或错过了什么?感谢。

BTW,实际问题是: 我有3个3gb文本文件,其中包含共同发生的单词元组及其频率,格式如下:
人类的大脑,1919年
汽车,石油,1920
人们,胜利,1923年

我需要将这些文件合并到一个文件中。合并时,必须对相同单词元组的频率求和。

1 个答案:

答案 0 :(得分:0)

仅执行GC所需的GC。默认收集器仅在使用所有空间时运行,任何更快的可能会有更高的开销。

在你的图表中,它表​​示你的旧收藏家从未跑过,而不是满满的(你只能在收集后告诉)收藏后它可能几乎是空的。

BTW单个单词可以轻松地使用8个对象作为您拥有的数据结构,或者每个单词大约256个字节的内存。如果你有5亿个单词,那么你需要大约128 GB的内存。我会尝试一个小得多的文件,看看在完整的GC之后它用了多少才能得到一个想法。