应用程序循环中的OutOfMemoryError,如何做得更好



我的应用程序因OutOfMemoryError:堆空间而崩溃。循环基本上是:

this.dbHandler = new DBHandler();
DataRetriever dataRetriever = new DataRetriever(this.dbHandler);
boolean loop = true;
System.out.println("Loop starts...");
while (loop == true) {
  long startTime = System.currentTimeMillis();
  this.retrieveDataAndStoreInDB(dataRetriever);
  long endTime = System.currentTimeMillis();
  System.out.println("Total time: " + Long.toString((endTime-startTime)/1000) + " seconds.");
  try {
    Thread.sleep(60000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}
System.out.println("Loop terminates.");

显然,内存是在retrieveDataAndStoreInDB(dataRetriever)中分配的。

  1. 我可以使用哪些工具来查找内存的分配位置
  2. 我应该遵循什么样的做法来避免这种情况?我将感谢链接到文档

编辑:好吧,我意识到我的问题太不具体了。首先,我的意图是像魔鬼一样无限期地运行这个程序。它应该每60秒重复一次数据检索和数据库存储。或者,我也可以每分钟运行一个cronjob并退出程序,但不幸的是,执行时间超过了60秒,而重复循环只需要大约12秒。另外,只有在第一个循环完成后,才会运行下一个循环。loop==true适用于未来,以防我出于某种原因想要中断循环,但目前尚未使用。我现在不能显示retrieveDataAndStoreInDB()的代码,因为我不在有代码的计算机上。但它正在深入研究,利用了我在一个大框架上写的几个类。

也许一个更好的问题是:假设我想在Java中每60秒重复一次执行流,那么我的方式合适吗,尤其是在内存管理方面?是的,我是Java初学者:)

感谢您的阅读!

在哪里更改循环值。

while (loop == true)

这是一个不定式循环。更改循环中的循环值。

您有两个选项来解决OutOfMemory问题,这可能是由隐藏方法中的内存泄漏引起的:

  • 或者使用java探查器通过标记对象来检查运行时行为,并检查哪些对象随时间增加
  • 或者,您可以在引发OutOfMemory错误时创建一个java转储文件,然后使用适当的工具检查转储文件中的对象

听起来您不知道所讨论的函数内部实际发生了什么,所以要吸取的教训是在使用工具之前更好地了解它们。)

对于内存泄漏,有几个工具可以用来分析实际发生的事情(即使是在预编译的代码中),例如NetBeans内置了Visual VM,它也可以作为Eclipse的插件和单机版使用。

使用这个工具,你可以让你的程序运行,它会跟踪每一个内存分配,以及它发生在哪里。

1.我可以使用哪个工具来查找内存分配位置?

JProfiler或jvisualvm

2.我应该遵循什么样的做法来避免这种情况?我将感谢链接到文档!

照本宣科http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683

最新更新