首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Java中处理OutOfMemoryError?

如何在Java中处理OutOfMemoryError?
EN

Stack Overflow用户
提问于 2019-04-07 23:42:57
回答 2查看 0关注 0票数 0

这个问题在这里已有答案:

  • 如何处理“java.lang.OutOfMemoryError:Java堆空间”错误? 18个答案

我必须序列化大约一百万个项目,当我运行我的代码时,我得到以下异常:

代码语言:javascript
复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at org.girs.TopicParser.dump(TopicParser.java:23)
    at org.girs.TopicParser.main(TopicParser.java:59)

我该如何处理?

EN

回答 2

Stack Overflow用户

发布于 2019-04-08 08:12:32

理想情况下,重构代码以减少内存使用。例如,也许您可​​以流输出输出而不是将整个内容保存在内存中。

或者,只需使用该-Xmx选项为JVM提供更多内存。

票数 0
EN

Stack Overflow用户

发布于 2019-04-08 08:58:28

我知道Java的官方答案是“我放弃了!”。对于那些在不允许内存不足(例如,编写操作系统或为非受保护的操作系统编写应用程序)的环境中编程的人来说,这一切都令人沮丧。

投降的意愿是必要的 - 您无法控制Java内存分配的每个方面,因此您无法保证您的程序在低内存条件下成功。但这并不意味着你必须不战而降。

但是,在战斗之前,你可以寻找避免这种需要的方法。也许你可以避免Java序列化,而是定义你自己的数据格式,不需要大量的内存分配来创建。序列化分配了大量内存,因为它保留了之前看到的对象的记录,因此如果它们再次出现,它可以通过数字引用它们而不是再次输出它们(这可能导致无限循环)。但这是因为它需要是通用的:根据您的数据结构,您可能能够定义一些文本/二进制/ XML /任何只能写入流的表示,而几乎不需要存储额外的状态。或者您可以安排所需的任何额外状态始终存储在对象中,而不是在序列化时创建。

如果你的应用程序执行一项使用大量内存的操作,但主要使用的内存少得多,特别是如果该操作是用户启动的,并且如果你找不到使用更少内存或提供更多内存的方法,那么它可能值得捕捉OutOfMemory。您可以通过向用户报告问题太大来恢复,并邀请他们将其修剪下来并再试一次。如果他们只花了一个小时来解决他们的问题,你就不会我只想摆脱计划并失去一切 - 你想让他们有机会为此做点什么。只要错误被捕获到堆栈中,超出的内存将在捕获错误时被取消引用,从而使VM至少有机会恢复。确保捕获常规事件处理代码下面的错误(在常规事件处理中捕获OutOfMemory会导致繁忙循环,因为您尝试向用户显示对话框,您仍然内存不足,并且您捕获另一个错误)。仅在您已识别为memory-hog的操作周围捕获它,以便不会捕获来自内存耗尽以外的代码的OutOfMemoryErrors。

即使在非交互式应用程序中,放弃失败的操作也是有意义的,但是程序本身可以继续运行,处理更多数据。这就是Web服务器管理多个进程的原因,如果一个页面请求由于内存不足而失败,服务器本身就不会崩溃。正如我在顶部所说的,单进程Java应用程序无法做出任何此类保证,但它们至少可以比默认值更强大。

也就是说,您的特定示例(序列化)可能不适合这种方法。特别是,用户在被告知存在问题时可能想要做的第一件事是保存他们的工作:但如果序列化失败,则可能无法保存。这不是你想要的,所以你可能不得不做一些实验和/或计算,并在尝试序列化之前手动限制程序允许的数百万项(基于它运行的内存量)。

这比尝试捕获错误并继续更强大,但不幸的是,很难找出确切的界限,所以你可能不得不谨慎一点。

如果在反序列化过程中发生错误,那么您就会更加坚定:如果您可以避免加载文件,则不应该在应用程序中出现致命错误。捕获错误更可能是合适的。

无论你做什么来处理缺乏资源(包括让错误取消应用程序),如果你关心后果,那么彻底测试它是非常重要的。困难在于你永远不知道代码中究竟会出现什么问题,因此通常需要测试大量的程序状态。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100001078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档