强制关闭Java

时间:2016-06-13 05:45:22

标签: java scala apache-spark

我的代码基本上是在Apache Spark上运行的,其中每个容器都在一个单独的JVM上运行。您为容器指定了某个内存限制。在我的程序中,一个容器完成了一个任务,但是当它试图执行另一个任务时,它会崩溃,说超出了内存限制。如果我在一个单独的容器中运行每个任务,它们总是正常运行。因此,看起来任务完成后会留下一些未封闭的资源,我无法在代码中找到,而那些未封闭的资源会增加容器的内存。所以,我的问题是,Java中是否有任何方法可以告诉JVM强制关闭所有资源。我还可以强制垃圾收集吗?我想在每项任务结束时执行这两个步骤。

2 个答案:

答案 0 :(得分:2)

你可以运行System.gc();,但我怀疑它会有所帮助 - 当内存不足时,Java会垃圾收集,只有在这需要太长时间才会失败。但是你描述的方式,你可能没有资源(=文件,套接字等)打开,但是大对象可以 。确保返回的对象不引用不必要的中间数据,并且不在static变量中存储除常量之外的任何内容。

使用例如visualvm或其他任何可以产生堆转储的内容,以查找占用内存的对象。

我知道Scala没有此功能。但Java 8有一个很好的功能,可以自动关闭外部资源,称为try-with-resources:

try(AutoCloseable foo = openSomeResource()) {
    doSomething();
}
离开此区块时,

会自动调用foo.close();,无论如何(例如,异常,返回)。如果你遵循这种模式,就很难让资源保持开放状态。但这指的是Java中所谓的“资源”,它们必须实现AutoCloseable接口,您可能没有资源打开,但可以访问的对象。据说有很多关于如何调试Java / Scala内存泄漏的教程。但通常第一步是获取堆转储以查看正在使用多少内存。某些工具(例如hprof,内置JVM)甚至可以使用行号显示分配站点

答案 1 :(得分:0)

也许你可以在jdk7或更多版本中使用try-with-resources

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
      }