Java 如何防止Scala代码中的内存泄漏?

Java 如何防止Scala代码中的内存泄漏?,java,scala,memory,memory-leaks,jvm,Java,Scala,Memory,Memory Leaks,Jvm,下面的代码首先读取一个文件,然后将这些信息放入HashMap(indexCategoryVectors)。HashMap包含一个String(键)和一个Long(值)。代码使用Long值通过RandomAccessFile访问另一个文件的特定位置 通过最后一个文件中读取的信息和一些操作,代码将新信息写入另一个文件(filename4)。积累信息的唯一变量是缓冲区(var buffer=new ArrayBuffer[Map[Int,Double]]()),但每次交互后都会清理缓冲区(buffer

下面的代码首先读取一个文件,然后将这些信息放入
HashMap
indexCategoryVectors
)。
HashMap
包含一个
String
(键)和一个
Long
(值)。代码使用
Long
值通过
RandomAccessFile
访问另一个文件的特定位置

通过最后一个文件中读取的信息和一些操作,代码将新信息写入另一个文件(
filename4
)。积累信息的唯一变量是缓冲区(
var buffer=new ArrayBuffer[Map[Int,Double]]()
),但每次交互后都会清理缓冲区(
buffer.clear

foreach的
foreach
命令应该运行超过400万次,我意识到内存中存在累积。我对代码进行了一百万次的交互测试,代码使用了超过32GB的内存。我不知道原因,可能是关于垃圾收集或者JVM中的其他任何东西。有人知道我能做些什么来防止内存泄漏吗

def main(args: Array[String]): Unit = {
  val indexCategoryVectors = getIndexCategoryVectors("filename1")
  val uriCategories = getMappingURICategories("filename2")

  val raf = new RandomAccessFile("filename3", "r")
  var buffer = new ArrayBuffer[Map[Int, Double]]()
  // Through each hashmap key.
  uriCategories.foreach(uri => {
    var emptyInterpretation = true        
    uri._2.foreach(categoria => {
        val position = indexCategoryVectors.get(categoria)
        // go to position
        raf.seek(position.get)
        var vectorSpace = parserVector(raf.readLine)
        buffer += vectorSpace
        //write the information of buffer in file
        writeInformation("filename4")
        buffer.clear
      }
    })
  })
  println("Success!")
}

允许JVM使用多少内存?您如何确定它使用了多少内存?如果您没有从内存错误中获得
OutOfMemoryError
,则可能没有泄漏,JVM只是在使用它提供的所有内存。如果您想了解其中的情况,请尝试使用JVM内存探查器,Oracle JDK附带了VisualVM。如果您为JVM提供32gb,并且使用32gb查看,则可以。正如@ThisIsNoZaku告诉您的,尝试使用VisualVM来理解代码是如何使用分配的内存的。另外,请参见。无论如何,您的代码也有一些可能的泄漏:如果在
while
循环中发生异常,则每个实例的代码都不会关闭输入流。请参阅关于Scala中的资源管理。这听起来很不寻常:如果它使用的内存比JVM使用的内存多(使用
-Xmx
),那么您应该得到
OutOfMemoryError
。当然,如果您的系统没有32gb可用空间,而您试图将这部分内存分配给JVM,那么操作系统将进行交换,但这与您的代码无关。无论如何,我认为您需要的是一个流处理框架,比如,因为您将处理大量数据,而不需要将所有数据都存储在内存中。